<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>中俊为 | we harmonyos</title>
    <meta name="generator" content="VuePress 1.9.7">
    <script>
          var _hmt = _hmt || [];
          (function() {
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?39485dba914ae63b24732b6a90688f0b";
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(hm, s);
          })();
      </script>
    <link rel="manifest" href="/manifest.webmanifest" crossorigin="use-credentials">
    <meta name="description" content="weharmonyos 鸿蒙论坛 鸿蒙注释 开源鸿蒙 鸿蒙源码 openharmony源码 HarmonyOS源码 HarmonyOS HarmonyOS生态 openharmony开发者文档 鸿蒙生态 鸿蒙系统 华为操作系统 鸿蒙研究站 开放原子开源基金会 百万汉字注解鸿蒙 百篇博客分析鸿蒙">
    <meta property="og:url" content="/blog/78.html">
    <meta property="og:site_name" content="中俊为 | we harmonyos">
    <meta property="og:description" content="本篇关键词：内核重定位、MMU、SVC栈、热启动、内核映射表 下载 &gt;&gt; 离线文档.鸿蒙内核源码分析(百篇博客分析.挖透鸿蒙内核).pdf.zip) 内核汇编相关篇为: v74.01 鸿蒙内核源码分析(编码方式) | 机器指令是如何编码的 ; v75.03 鸿蒙内核源码分析(汇编基础) | CPU上班也要打卡; v76.04 鸿蒙内核源码分析(汇编传参">
    <meta property="og:type" content="article">
    <meta property="og:locale" content="en-US">
    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:image:alt" content="中俊为 | we harmonyos">
    <meta name="theme-color" content="#46bd87">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
    
    <link rel="preload" href="/assets/css/0.styles.087eb7d3.css" as="style"><link rel="preload" href="/assets/js/app.9a8b95d8.js" as="script"><link rel="preload" href="/assets/js/vendors~layout-Layout.c1e797d4.js" as="script"><link rel="preload" href="/assets/js/vendors~layout-Blog~layout-Layout~layout-NotFound.f75cf258.js" as="script"><link rel="preload" href="/assets/js/page--63d3c5b0.b587d38f.js" as="script"><link rel="prefetch" href="/assets/js/160.a8046d43.js"><link rel="prefetch" href="/assets/js/161.29f8564f.js"><link rel="prefetch" href="/assets/js/162.249ee491.js"><link rel="prefetch" href="/assets/js/163.c57d1577.js"><link rel="prefetch" href="/assets/js/164.7a788aaa.js"><link rel="prefetch" href="/assets/js/165.c333afb2.js"><link rel="prefetch" href="/assets/js/166.9bcb7cd6.js"><link rel="prefetch" href="/assets/js/layout-Blog.4a9781d1.js"><link rel="prefetch" href="/assets/js/layout-Layout.7e277e0b.js"><link rel="prefetch" href="/assets/js/layout-NotFound.9326b14e.js"><link rel="prefetch" href="/assets/js/layout-Slide.8dd861e4.js"><link rel="prefetch" href="/assets/js/page--00854288.e2bc8e8a.js"><link rel="prefetch" href="/assets/js/page--00f8db0a.b2a35fe6.js"><link rel="prefetch" href="/assets/js/page--03ad6df0.d48f4c19.js"><link rel="prefetch" href="/assets/js/page--04b12ba8.e8add78d.js"><link rel="prefetch" href="/assets/js/page--070d2528.d24cd503.js"><link rel="prefetch" href="/assets/js/page--086560f0.a6be2844.js"><link rel="prefetch" href="/assets/js/page--090ad32d.fc7da3c3.js"><link rel="prefetch" href="/assets/js/page--0c054030.2886024e.js"><link rel="prefetch" href="/assets/js/page--0d9507c8.a27dee03.js"><link rel="prefetch" href="/assets/js/page--10bd3330.b5165172.js"><link rel="prefetch" href="/assets/js/page--1233b0b2.b5caca9c.js"><link rel="prefetch" href="/assets/js/page--13650e88.61330a2b.js"><link rel="prefetch" href="/assets/js/page--14c850b1.d9a40c31.js"><link rel="prefetch" href="/assets/js/page--15752630.25f9c756.js"><link rel="prefetch" href="/assets/js/page--19150570.58df8995.js"><link rel="prefetch" href="/assets/js/page--19ecf128.130d012b.js"><link rel="prefetch" href="/assets/js/page--1c48eaa8.9a689e30.js"><link rel="prefetch" href="/assets/js/page--1d4dfe96.bd551921.js"><link rel="prefetch" href="/assets/js/page--1dccf870.03d7d9cc.js"><link rel="prefetch" href="/assets/js/page--2074d3c8.06bf5706.js"><link rel="prefetch" href="/assets/js/page--22213c96.e703257a.js"><link rel="prefetch" href="/assets/js/page--2284eb70.514124de.js"><link rel="prefetch" href="/assets/js/page--22d0cd48.11ea1522.js"><link rel="prefetch" href="/assets/js/page--252cc6c8.f9acae83.js"><link rel="prefetch" href="/assets/js/page--2624cab0.4535fea2.js"><link rel="prefetch" href="/assets/js/page--269ff8f9.012e8ae6.js"><link rel="prefetch" href="/assets/js/page--26fcb668.35b2da5d.js"><link rel="prefetch" href="/assets/js/page--2958afe8.216913bc.js"><link rel="prefetch" href="/assets/js/page--2adcbdb0.6dcb4c27.js"><link rel="prefetch" href="/assets/js/page--2bb4a968.aac31797.js"><link rel="prefetch" href="/assets/js/page--2d849908.7bb4e817.js"><link rel="prefetch" href="/assets/js/page--2e10a2e8.42bef48d.js"><link rel="prefetch" href="/assets/js/page--2f94b0b0.0c993df5.js"><link rel="prefetch" href="/assets/js/page--2fe09288.77769dcb.js"><link rel="prefetch" href="/assets/js/page--323c8c08.254a5f78.js"><link rel="prefetch" href="/assets/js/page--33348ff0.a5f99eb0.js"><link rel="prefetch" href="/assets/js/page--340c7ba8.2c9570cb.js"><link rel="prefetch" href="/assets/js/page--34988588.8c8d0363.js"><link rel="prefetch" href="/assets/js/page--36687528.67d84e0d.js"><link rel="prefetch" href="/assets/js/page--37d6dfd6.88e9cd42.js"><link rel="prefetch" href="/assets/js/page--37ec82f0.5419c82d.js"><link rel="prefetch" href="/assets/js/page--37f7cf15.65f72e55.js"><link rel="prefetch" href="/assets/js/page--38c46ea8.5d5150f9.js"><link rel="prefetch" href="/assets/js/page--3a945e48.bf9758fb.js"><link rel="prefetch" href="/assets/js/page--3ab2204c.e08d6316.js"><link rel="prefetch" href="/assets/js/page--3b206828.d83e3926.js"><link rel="prefetch" href="/assets/js/page--3ca475f0.49e5acce.js"><link rel="prefetch" href="/assets/js/page--3cf057c8.8364331d.js"><link rel="prefetch" href="/assets/js/page--3f4c5148.587a8360.js"><link rel="prefetch" href="/assets/js/page--40445530.486bb516.js"><link rel="prefetch" href="/assets/js/page--411c40e8.2eedba0e.js"><link rel="prefetch" href="/assets/js/page--41a84ac8.f4a360a3.js"><link rel="prefetch" href="/assets/js/page--4220f8b5.19b4371f.js"><link rel="prefetch" href="/assets/js/page--43783a68.4faf0866.js"><link rel="prefetch" href="/assets/js/page--44fc4830.a160662c.js"><link rel="prefetch" href="/assets/js/page--45d433e8.560fef87.js"><link rel="prefetch" href="/assets/js/page--47a42388.052314b4.js"><link rel="prefetch" href="/assets/js/page--47d07816.66731286.js"><link rel="prefetch" href="/assets/js/page--48302d68.8d6493cf.js"><link rel="prefetch" href="/assets/js/page--49b43b30.e3684736.js"><link rel="prefetch" href="/assets/js/page--4a001d08.47f7ec45.js"><link rel="prefetch" href="/assets/js/page--4c5c1688.b7ec1f32.js"><link rel="prefetch" href="/assets/js/page--4d541a70.ee807705.js"><link rel="prefetch" href="/assets/js/page--4e2c0628.4f7105a4.js"><link rel="prefetch" href="/assets/js/page--4eb81008.725d26fe.js"><link rel="prefetch" href="/assets/js/page--5087ffa8.dac2aae0.js"><link rel="prefetch" href="/assets/js/page--520c0d70.2beedefb.js"><link rel="prefetch" href="/assets/js/page--52e3f928.2645087c.js"><link rel="prefetch" href="/assets/js/page--53cd0b44.96d4a285.js"><link rel="prefetch" href="/assets/js/page--54eb2c5e.27eb702b.js"><link rel="prefetch" href="/assets/js/page--553ff2a8.fba8ee4f.js"><link rel="prefetch" href="/assets/js/page--5686ab01.547b633c.js"><link rel="prefetch" href="/assets/js/page--56c40070.4e35708a.js"><link rel="prefetch" href="/assets/js/page--570fe248.2b301b36.js"><link rel="prefetch" href="/assets/js/page--596bdbc8.c74cd724.js"><link rel="prefetch" href="/assets/js/page--5a63dfb0.bbd49a9b.js"><link rel="prefetch" href="/assets/js/page--5bc7d548.eda26865.js"><link rel="prefetch" href="/assets/js/page--5f1bd2b0.e02cf88d.js"><link rel="prefetch" href="/assets/js/page--5ff3be68.b2b0e76e.js"><link rel="prefetch" href="/assets/js/page--624fb7e8.666fdc84.js"><link rel="prefetch" href="/assets/js/page--68d79a88.86f62e4d.js"><link rel="prefetch" href="/assets/js/page--6c2b97f0.ed46abea.js"><link rel="prefetch" href="/assets/js/page--6cc6a596.b3827451.js"><link rel="prefetch" href="/assets/js/page--6ea7a148.61a9bc10.js"><link rel="prefetch" href="/assets/js/page--70e38af0.eb8ffc53.js"><link rel="prefetch" href="/assets/js/page--7180d470.73a3a20e.js"><link rel="prefetch" href="/assets/js/page--752f83e8.d5c31640.js"><link rel="prefetch" href="/assets/js/page--778b7d68.5e8e5ea9.js"><link rel="prefetch" href="/assets/js/page--7bb76688.53e305e3.js"><link rel="prefetch" href="/assets/js/page--7c59a86a.ecf88c30.js"><link rel="prefetch" href="/assets/js/page--7df35030.cfa388f4.js"><link rel="prefetch" href="/assets/js/page--7e136008.230e9a15.js"><link rel="prefetch" href="/assets/js/page--89935db0.f79f9e25.js"><link rel="prefetch" href="/assets/js/page--96a322f0.412d537f.js"><link rel="prefetch" href="/assets/js/page--9b5b15f0.a5231547.js"><link rel="prefetch" href="/assets/js/page--a3b2e830.f4ba68fa.js"><link rel="prefetch" href="/assets/js/page--a86adb30.ec08486b.js"><link rel="prefetch" href="/assets/js/page--ad22ce30.4872eca4.js"><link rel="prefetch" href="/assets/js/page--b0c2ad70.8637057e.js"><link rel="prefetch" href="/assets/js/page--b57aa070.43215f9e.js"><link rel="prefetch" href="/assets/js/page--ba329370.b5f22d13.js"><link rel="prefetch" href="/assets/js/page--bdd272b0.aff1d1a9.js"><link rel="prefetch" href="/assets/js/page--c28a65b0.978514c4.js"><link rel="prefetch" href="/assets/js/page--c606edca.49d3396e.js"><link rel="prefetch" href="/assets/js/page--c74258b0.f85195bc.js"><link rel="prefetch" href="/assets/js/page--cae237f0.8a976cc1.js"><link rel="prefetch" href="/assets/js/page--cf9a2af0.7ad20ea2.js"><link rel="prefetch" href="/assets/js/page--d4521df0.a0a74934.js"><link rel="prefetch" href="/assets/js/page--d7f1fd30.160f138a.js"><link rel="prefetch" href="/assets/js/page--dca9f030.9127ab28.js"><link rel="prefetch" href="/assets/js/page--e161e330.34876a6f.js"><link rel="prefetch" href="/assets/js/page--e4f35ef4.690d3ccb.js"><link rel="prefetch" href="/assets/js/page--e501c270.8dc088ee.js"><link rel="prefetch" href="/assets/js/page--e9b9b570.b94764ed.js"><link rel="prefetch" href="/assets/js/page--ea4e0a70.94492571.js"><link rel="prefetch" href="/assets/js/page--ee71a870.b9944792.js"><link rel="prefetch" href="/assets/js/page--f21187b0.d00a5788.js"><link rel="prefetch" href="/assets/js/page--f6c97ab0.ecb91d64.js"><link rel="prefetch" href="/assets/js/page--fb816db0.c1f07c37.js"><link rel="prefetch" href="/assets/js/page--fcf2f51e.71000d71.js"><link rel="prefetch" href="/assets/js/page--ff214cf0.aaa8b0fc.js"><link rel="prefetch" href="/assets/js/page-GN.2f20b55f.js"><link rel="prefetch" href="/assets/js/page-GNFrequentlyAskedQuestions.24e61c26.js"><link rel="prefetch" href="/assets/js/page-GNLanguageandOperation.35e22ff2.js"><link rel="prefetch" href="/assets/js/page-GNQuickStartguide.7cd8e521.js"><link rel="prefetch" href="/assets/js/page-GNReference.1d5d0c6c.js"><link rel="prefetch" href="/assets/js/page-GNSimpleBuildExample.2eb0b7eb.js"><link rel="prefetch" href="/assets/js/page-GNStyleGuide.8a407135.js"><link rel="prefetch" href="/assets/js/page-GNU汇编教程.d208e4d7.js"><link rel="prefetch" href="/assets/js/page-GNvimsyntaxplugin.58d1459e.js"><link rel="prefetch" href="/assets/js/page-GN快速入门.b708bb6a.js"><link rel="prefetch" href="/assets/js/page-Home.97282d71.js"><link rel="prefetch" href="/assets/js/page-HowGNhandlescross-compiling.6ca64957.js"><link rel="prefetch" href="/assets/js/page-Introduction.292088e0.js"><link rel="prefetch" href="/assets/js/page-ninja快速入门.92729e64.js"><link rel="prefetch" href="/assets/js/page-《孙子兵法》全文.402792c5.js"><link rel="prefetch" href="/assets/js/page-《论语》全文.85da0da0.js"><link rel="prefetch" href="/assets/js/page-《诗经》全文.99ebeb52.js"><link rel="prefetch" href="/assets/js/page-《道德经》全文.43627e4e.js"><link rel="prefetch" href="/assets/js/page-两个文档.eb8dd1b7.js"><link rel="prefetch" href="/assets/js/page-主流站点覆盖定期同步更新.1ad02178.js"><link rel="prefetch" href="/assets/js/page-手机版电脑版.b5e8dfea.js"><link rel="prefetch" href="/assets/js/page-捐助方式.6ca91d44.js"><link rel="prefetch" href="/assets/js/page-来源LiteOS和LiteOS-A内核图解.8fa16705.js"><link rel="prefetch" href="/assets/js/page-电脑版手机版.67a0b4a4.js"><link rel="prefetch" href="/assets/js/page-编程语言相关书籍.d9adf7cb.js"><link rel="prefetch" href="/assets/js/page-鸿蒙内核源码分析.bbb451c7.js"><link rel="prefetch" href="/assets/js/vendors~flowchart.46b2de48.js"><link rel="prefetch" href="/assets/js/vendors~mermaid.627fb4be.js"><link rel="prefetch" href="/assets/js/vendors~photo-swipe.cbde97f9.js"><link rel="prefetch" href="/assets/js/vendors~reveal.77b21b7e.js">
    <link rel="stylesheet" href="/assets/css/0.styles.087eb7d3.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container has-navbar has-sidebar has-anchor"><header class="navbar"><!----> <div class="content__navbar-start"></div> <button title="Sidebar Button" class="sidebar-button"><span class="icon"></span></button> <a href="/" class="home-link router-link-active"><!----> <!----> <span class="site-name can-hide">中俊为 | we harmonyos</span></a> <!----> <div class="content__navbar-center"></div> <div class="links"><button tabindex="-1" aria-hidden="true" class="color-button"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="skin-icon"><path d="M224 800c0 9.6 3.2 44.8 6.4 54.4 6.4 48-48 76.8-48 76.8s80 41.6 147.2 0 134.4-134.4
        38.4-195.2c-22.4-12.8-41.6-19.2-57.6-19.2C259.2 716.8 227.2 761.6 224 800zM560 675.2l-32
        51.2c-51.2 51.2-83.2 32-83.2 32 25.6 67.2 0 112-12.8 128 25.6 6.4 51.2 9.6 80 9.6 54.4 0
        102.4-9.6 150.4-32l0 0c3.2 0 3.2-3.2 3.2-3.2 22.4-16 12.8-35.2
        6.4-44.8-9.6-12.8-12.8-25.6-12.8-41.6 0-54.4 60.8-99.2 137.6-99.2 6.4 0 12.8 0 22.4
        0 12.8 0 38.4 9.6 48-25.6 0-3.2 0-3.2 3.2-6.4 0-3.2 3.2-6.4 3.2-6.4 6.4-16 6.4-16 6.4-19.2
        9.6-35.2 16-73.6 16-115.2 0-105.6-41.6-198.4-108.8-268.8C704 396.8 560 675.2 560 675.2zM224
        419.2c0-28.8 22.4-51.2 51.2-51.2 28.8 0 51.2 22.4 51.2 51.2 0 28.8-22.4 51.2-51.2 51.2C246.4
        470.4 224 448 224 419.2zM320 284.8c0-22.4 19.2-41.6 41.6-41.6 22.4 0 41.6 19.2 41.6 41.6 0
        22.4-19.2 41.6-41.6 41.6C339.2 326.4 320 307.2 320 284.8zM457.6 208c0-12.8 12.8-25.6 25.6-25.6
        12.8 0 25.6 12.8 25.6 25.6 0 12.8-12.8 25.6-25.6 25.6C470.4 233.6 457.6 220.8 457.6 208zM128
        505.6C128 592 153.6 672 201.6 736c28.8-60.8 112-60.8 124.8-60.8-16-51.2 16-99.2
        16-99.2l316.8-422.4c-48-19.2-99.2-32-150.4-32C297.6 118.4 128 291.2 128 505.6zM764.8
        86.4c-22.4 19.2-390.4 518.4-390.4 518.4-22.4 28.8-12.8 76.8 22.4 99.2l9.6 6.4c35.2 22.4
        80 12.8 99.2-25.6 0 0 6.4-12.8 9.6-19.2 54.4-105.6 275.2-524.8 288-553.6
        6.4-19.2-3.2-32-19.2-32C777.6 76.8 771.2 80 764.8 86.4z"></path></svg> <div class="color-picker-menu" style="display:none;"><div class="theme-options"><ul class="themecolor-select"><label for="themecolor-select">Theme Color:</label> <li><span class="default-theme"></span></li> </ul> <div class="darkmode-toggle"><label for="darkmode-toggle" class="desc">Theme Mode:</label> <div class="darkmode-switch"><div class="item day"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon light-icon"><path d="M512 256a42.667 42.667 0 0 0 42.667-42.667V128a42.667 42.667 0 0 0-85.334 0v85.333A42.667 42.667 0 0 0 512 256zm384 213.333h-85.333a42.667 42.667 0 0 0 0 85.334H896a42.667 42.667 0 0 0 0-85.334zM256 512a42.667 42.667 0 0 0-42.667-42.667H128a42.667 42.667 0 0 0 0 85.334h85.333A42.667 42.667 0 0 0 256 512zm9.387-298.667a42.667 42.667 0 0 0-59.307 62.72l61.44 59.307a42.667 42.667 0 0 0 31.147 11.947 42.667 42.667 0 0 0 30.72-13.227 42.667 42.667 0 0 0 0-60.16zm459.946 133.974a42.667 42.667 0 0 0 29.44-11.947l61.44-59.307a42.667 42.667 0 0 0-57.6-62.72l-61.44 60.587a42.667 42.667 0 0 0 0 60.16 42.667 42.667 0 0 0 28.16 13.227zM512 768a42.667 42.667 0 0 0-42.667 42.667V896a42.667 42.667 0 0 0 85.334 0v-85.333A42.667 42.667 0 0 0 512 768zm244.48-79.36a42.667 42.667 0 0 0-59.307 61.44l61.44 60.587a42.667 42.667 0 0 0 29.44 11.946 42.667 42.667 0 0 0 30.72-12.8 42.667 42.667 0 0 0 0-60.586zm-488.96 0-61.44 59.307a42.667 42.667 0 0 0 0 60.586 42.667 42.667 0 0 0 30.72 12.8 42.667 42.667 0 0 0 28.587-10.666l61.44-59.307a42.667 42.667 0 0 0-59.307-61.44zM512 341.333A170.667 170.667 0 1 0 682.667 512 170.667 170.667 0 0 0 512 341.333z" fill="currentColor"></path></svg></div> <div class="item auto active"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon auto-icon"><path d="M460.864 539.072H564.8L510.592 376l-49.728 163.072zM872 362.368V149.504H659.648L510.528 0l-149.12 149.504H149.12v212.928L0 511.872l149.12 149.504v212.928h212.352l149.12 149.504 149.12-149.504h212.352V661.376l149.12-149.504L872 362.368zM614.464 693.12l-31.616-90.624H438.272l-31.616 90.624h-85.888l144.576-407.68h90.368l144.576 407.68h-85.824zm0 0" fill="currentColor"></path></svg></div> <div class="item night"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon dark-icon"><path d="M935.539 630.402c-11.43-11.432-28.674-14.739-43.531-8.354-46.734 20.103-96.363 30.297-147.508 30.297-99.59 0-193.221-38.784-263.64-109.203-108.637-108.637-139.61-270.022-78.908-411.148a39.497 39.497 0 0 0-51.886-51.887c-52.637 22.64-100.017 54.81-140.826 95.616-85.346 85.346-132.346 198.821-132.346 319.52 0 120.7 47.001 234.172 132.347 319.519S408.063 947.11 528.76 947.11c120.7 0 234.172-47.003 319.52-132.351 40.809-40.81 72.978-88.19 95.616-140.826a39.497 39.497 0 0 0-8.356-43.532z" fill="currentColor"></path></svg></div></div> <!----></div></div></div></button> <div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/" class="nav-link router-link-active"><!---->
  首页
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="文档中心" class="dropdown-title"><span class="title"><!---->
        文档中心
      </span> <span class="arrow"></span></button> <ul class="nav-dropdown"><li class="dropdown-item"><a href="http://open.weharmonyos.com/zh-cn/readme/Readme-CN.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  子系统
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><a href="http://open.weharmonyos.com/zh-cn/device-dev/website.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  南向
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><a href="http://open.weharmonyos.com/zh-cn/application-dev/website.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  北向
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="博客中心" class="dropdown-title"><span class="title"><!---->
        博客中心
      </span> <span class="arrow"></span></button> <ul class="nav-dropdown"><li class="dropdown-item"><a href="/blog/101.html" class="nav-link"><!---->
  总目录
</a></li><li class="dropdown-item"><a href="/blog/index/1_base.html" class="nav-link"><!---->
  基础知识
</a></li><li class="dropdown-item"><a href="/blog/index/2_process.html" class="nav-link"><!---->
  进程管理
</a></li><li class="dropdown-item"><a href="/blog/index/3_task.html" class="nav-link"><!---->
  任务管理
</a></li><li class="dropdown-item"><a href="/blog/index/4_mem.html" class="nav-link"><!---->
  内存管理
</a></li><li class="dropdown-item"><a href="/blog/index/5_ipc.html" class="nav-link"><!---->
  进程通讯
</a></li><li class="dropdown-item"><a href="/blog/index/6_fs.html" class="nav-link"><!---->
  文件系统
</a></li><li class="dropdown-item"><a href="/blog/index/7_hw.html" class="nav-link"><!---->
  软硬接口
</a></li><li class="dropdown-item"><a href="/blog/index/8_asm.html" class="nav-link"><!---->
  内核汇编
</a></li><li class="dropdown-item"><a href="/blog/index/9_run.html" class="nav-link"><!---->
  编译运行
</a></li><li class="dropdown-item"><a href="/blog/index/10_test.html" class="nav-link"><!---->
  调测工具
</a></li><li class="dropdown-item"><a href="/blog/index/0_so.html" class="nav-link"><!---->
  前因后果
</a></li><li class="dropdown-item"><a href="/extsite.html" class="nav-link"><!---->
  前往 &gt;&gt; 外站
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="论坛中心" class="dropdown-title"><span class="title"><!---->
        论坛中心
      </span> <span class="arrow"></span></button> <ul class="nav-dropdown"><li class="dropdown-item"><a href="http://bbs.weharmonyos.com" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  论坛首页
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><a href="http://bbs.weharmonyos.com/forum-42-1.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  问题建议
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="手册中心" class="dropdown-title"><span class="title"><!---->
        手册中心
      </span> <span class="arrow"></span></button> <ul class="nav-dropdown"><li class="dropdown-item"><a href="http://doxygen.weharmonyos.com/index.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  内核参考手册
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><a href="/compile/assembly.html" class="nav-link"><!---->
  gnu 汇编教程
</a></li><li class="dropdown-item"><a href="/compile/gn/docs/" class="nav-link"><!---->
  gn 参考手册
</a></li><li class="dropdown-item"><a href="/compile/ninja/Readme-CN.html" class="nav-link"><!---->
  ninja 参考手册
</a></li><li class="dropdown-item"><a href="/compile/fhs.html" class="nav-link"><!---->
  fhs 规范
</a></li></ul></div></div><div class="nav-item"><a href="/donate.html" class="nav-link"><!---->
  赞助中心
</a></div></nav> <!----> <!----> <!----> <div class="content__navbar-end"></div></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><!----> <!----> <div class="content__sidebar-top"></div> <nav class="sidebar-nav-links"><div class="nav-item"><a href="/" class="nav-link router-link-active"><!---->
  首页
</a></div><div class="nav-item"><div class="mobile-dropdown-wrapper"><button type="button" aria-label="文档中心" class="dropdown-title"><span class="title"><!---->
      文档中心
    </span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="http://open.weharmonyos.com/zh-cn/readme/Readme-CN.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  子系统
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="http://open.weharmonyos.com/zh-cn/device-dev/website.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  南向
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="http://open.weharmonyos.com/zh-cn/application-dev/website.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  北向
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><div class="mobile-dropdown-wrapper"><button type="button" aria-label="博客中心" class="dropdown-title"><span class="title"><!---->
      博客中心
    </span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/blog/101.html" class="nav-link"><!---->
  总目录
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/1_base.html" class="nav-link"><!---->
  基础知识
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/2_process.html" class="nav-link"><!---->
  进程管理
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/3_task.html" class="nav-link"><!---->
  任务管理
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/4_mem.html" class="nav-link"><!---->
  内存管理
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/5_ipc.html" class="nav-link"><!---->
  进程通讯
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/6_fs.html" class="nav-link"><!---->
  文件系统
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/7_hw.html" class="nav-link"><!---->
  软硬接口
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/8_asm.html" class="nav-link"><!---->
  内核汇编
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/9_run.html" class="nav-link"><!---->
  编译运行
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/10_test.html" class="nav-link"><!---->
  调测工具
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/0_so.html" class="nav-link"><!---->
  前因后果
</a></li><li class="dropdown-item"><!----> <a href="/extsite.html" class="nav-link"><!---->
  前往 &gt;&gt; 外站
</a></li></ul></div></div><div class="nav-item"><div class="mobile-dropdown-wrapper"><button type="button" aria-label="论坛中心" class="dropdown-title"><span class="title"><!---->
      论坛中心
    </span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="http://bbs.weharmonyos.com" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  论坛首页
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="http://bbs.weharmonyos.com/forum-42-1.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  问题建议
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><div class="mobile-dropdown-wrapper"><button type="button" aria-label="手册中心" class="dropdown-title"><span class="title"><!---->
      手册中心
    </span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="http://doxygen.weharmonyos.com/index.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  内核参考手册
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="/compile/assembly.html" class="nav-link"><!---->
  gnu 汇编教程
</a></li><li class="dropdown-item"><!----> <a href="/compile/gn/docs/" class="nav-link"><!---->
  gn 参考手册
</a></li><li class="dropdown-item"><!----> <a href="/compile/ninja/Readme-CN.html" class="nav-link"><!---->
  ninja 参考手册
</a></li><li class="dropdown-item"><!----> <a href="/compile/fhs.html" class="nav-link"><!---->
  fhs 规范
</a></li></ul></div></div><div class="nav-item"><a href="/donate.html" class="nav-link"><!---->
  赞助中心
</a></div> <!----></nav> <!----> <div class="content__sidebar-center"></div> <ul class="sidebar-links"><li><a href="/blog/101.html" class="sidebar-link">总目录</a></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">基础知识 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">进程管理 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">任务管理 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">内存管理 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">通讯机制 | 14</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">文件系统 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">硬件架构 | 9</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable open"><!----> <span class="title">内核汇编 | 10</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/blog/index/8_asm.html" class="sidebar-link">本章目录</a></li><li><a href="/blog/74.html" class="sidebar-link">编码方式</a></li><li><a href="/blog/75.html" class="sidebar-link">汇编基础</a></li><li><a href="/blog/76.html" class="sidebar-link">汇编传参</a></li><li><a href="/blog/77.html" class="sidebar-link">链接脚本</a></li><li><a href="/blog/78.html" aria-current="page" class="active sidebar-link">内核启动</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/blog/79.html" class="sidebar-link">进程切换</a></li><li><a href="/blog/80.html" class="sidebar-link">任务切换</a></li><li><a href="/blog/81.html" class="sidebar-link">中断切换</a></li><li><a href="/blog/82.html" class="sidebar-link">异常接管</a></li><li><a href="/blog/83.html" class="sidebar-link">缺页中断</a></li></ul></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">编译运行 | 13</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">调测工具 | 4</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">前因后果 | 4</span> <span class="arrow right"></span></p> <!----></section></li></ul> <!----> <div class="content__sidebar-bottom"></div> <!----></aside> <main class="page"><nav class="breadcrumb disable"><!----></nav> <!----> <div class="content__page-top"></div> <div vocab="https://schema.org/" typeof="Article" class="page-title"><h1><!----> <span property="headline"></span></h1> <div class="page-info"><!----> </div> <!----> <hr></div> <div class="anchor-place-holder"><aside id="anchor"><div class="anchor-wrapper"><ul class="anchor-list"><li class="anchor"><a href="/blog/78.html#uboot" class="anchor-link heading3"><div>Uboot</div></a></li><li class="anchor"><a href="/blog/78.html#内核入口" class="anchor-link heading3"><div>内核入口</div></a></li><li class="anchor"><a href="/blog/78.html#百文说内核-抓住主脉络" class="anchor-link heading3"><div>百文说内核 | 抓住主脉络</div></a></li><li class="anchor"><a href="/blog/78.html#百万注源码-处处扣细节" class="anchor-link heading3"><div>百万注源码 | 处处扣细节</div></a></li><li class="anchor"><a href="/blog/78.html#关注不迷路-代码即人生" class="anchor-link heading3"><div>关注不迷路 | 代码即人生</div></a></li></ul></div></aside></div> <!----> <div class="content__content-top"></div> <div class="theme-default-content content__default"><p>本篇关键词：内核重定位、MMU、SVC栈、热启动、内核映射表</p> <p><a href="https://weharmony.gitee.io/blog/78.html" target="_blank" rel="noopener noreferrer"><img src="https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/index/78.png" alt=""></a></p> <p><a href="https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/pdf/%E9%B8%BF%E8%92%99%E5%86%85%E6%A0%B8%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90(%E7%99%BE%E7%AF%87%E5%8D%9A%E5%AE%A2%E5%88%86%E6%9E%90.%E6%8C%96%E9%80%8F%E9%B8%BF%E8%92%99%E5%86%85%E6%A0%B8).zip" target="_blank" rel="noopener noreferrer">下载 &gt;&gt; 离线文档.鸿蒙内核源码分析(百篇博客分析.挖透鸿蒙内核).pdf</a></p> <p>内核汇编相关篇为:</p> <ul><li><a href="http://weharmonyos.com/blog/74.html" target="_blank" rel="noopener noreferrer">v74.01 鸿蒙内核源码分析(编码方式) | 机器指令是如何编码的 </a></li> <li><a href="http://weharmonyos.com/blog/75.html" target="_blank" rel="noopener noreferrer">v75.03 鸿蒙内核源码分析(汇编基础) | CPU上班也要打卡</a></li> <li><a href="http://weharmonyos.com/blog/76.html" target="_blank" rel="noopener noreferrer">v76.04 鸿蒙内核源码分析(汇编传参) | 如何传递复杂的参数</a></li> <li><a href="http://weharmonyos.com/blog/77.html" target="_blank" rel="noopener noreferrer">v77.01 鸿蒙内核源码分析(链接脚本) | 正在制作中 ... </a></li> <li><a href="http://weharmonyos.com/blog/78.html" target="_blank" rel="noopener noreferrer">v78.01 鸿蒙内核源码分析(内核启动) | 从汇编到main()</a></li> <li><a href="http://weharmonyos.com/blog/79.html" target="_blank" rel="noopener noreferrer">v79.01 鸿蒙内核源码分析(进程切换) | 正在制作中 ... </a></li> <li><a href="http://weharmonyos.com/blog/80.html" target="_blank" rel="noopener noreferrer">v80.03 鸿蒙内核源码分析(任务切换) | 看汇编如何切换任务</a></li> <li><a href="http://weharmonyos.com/blog/81.html" target="_blank" rel="noopener noreferrer">v81.05 鸿蒙内核源码分析(中断切换) | 系统因中断活力四射</a></li> <li><a href="http://weharmonyos.com/blog/82.html" target="_blank" rel="noopener noreferrer">v82.06 鸿蒙内核源码分析(异常接管) | 社会很单纯 复杂的是人</a></li> <li><a href="http://weharmonyos.com/blog/83.html" target="_blank" rel="noopener noreferrer">v83.01 鸿蒙内核源码分析(缺页中断) | 正在制作中 ... </a></li></ul> <p>这应该是系列篇最难写的一篇，全是汇编代码，需大量的底层知识，涉及协处理器，内核镜像重定位，创建内核映射表，初始化 <strong>CPU</strong> 模式栈，热启动，到最后熟悉的 <strong>main()</strong> 。</p> <h3 id="uboot">Uboot</h3> <p>在 <strong>PC寄存器</strong> 指向内核第一条指令之前，需要先将内核从 <strong>flash</strong> 加载到内存指定位置，这部分工作由引导程序 <strong>uboot (与硬件强相关)</strong> 完成，而它并不在 <strong>kernel_liteos_a (与硬件弱相关)</strong> 工程中，而在工程 <a href="https://gitee.com/openharmony/device_hisilicon_third_party_uboot" target="_blank" rel="noopener noreferrer"> u-boot-2020.01中 ，前往 &gt;&gt;</a> ，所以系列篇不对引导程序详细说明，后续有机会再分析。引导结束后舞台就交给了内核 <strong>reset_vector</strong> 处 ，一切由此开始。</p> <h3 id="内核入口">内核入口</h3> <p>在链接文件 <strong>liteos.ld</strong> 中可知内核的入口地址为 <code>ENTRY(reset_vector)</code> ， 分别出现在reset_vector_mp.S (多核启动) 和 reset_vector_up.S(单核启动)，系列篇研究多核启动的情况。代码可结合 <strong>(协处理器篇)</strong> 看更容易懂。</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code>reset_vector<span class="token operator">:</span> <span class="token comment">//内核启动入口</span>
    <span class="token comment">/* clear register TPIDRPRW */</span>
    mov     r0<span class="token punctuation">,</span> #<span class="token number">0</span>					<span class="token comment">//r0 = 0</span>
    mcr     p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r0<span class="token punctuation">,</span> c13<span class="token punctuation">,</span> c0<span class="token punctuation">,</span> <span class="token number">4</span>	<span class="token comment">//复位线程标识符寄存器TPIDRPRW , 不复位将导致系统不能启动</span>
    <span class="token comment">/* do some early cpu setup: i/d cache disable, mmu disabled */</span>
    mrc     p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r0<span class="token punctuation">,</span> c1<span class="token punctuation">,</span> c0<span class="token punctuation">,</span> <span class="token number">0</span>	<span class="token comment">//System Control Register-SCTLR | 读取系统控制寄存器内容</span>
    bic     r0<span class="token punctuation">,</span> #<span class="token punctuation">(</span><span class="token number">1</span><span class="token operator">&lt;&lt;</span><span class="token number">12</span><span class="token punctuation">)</span>			<span class="token comment">//禁用指令缓存功能</span>
    bic     r0<span class="token punctuation">,</span> #<span class="token punctuation">(</span><span class="token number">1</span><span class="token operator">&lt;&lt;</span><span class="token number">2</span> <span class="token operator">|</span> <span class="token number">1</span><span class="token operator">&lt;&lt;</span><span class="token number">0</span><span class="token punctuation">)</span>		<span class="token comment">//禁用数据和TLB的缓存功能(bit2) | mmu功能(bit0)</span>
    mcr     p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r0<span class="token punctuation">,</span> c1<span class="token punctuation">,</span> c0<span class="token punctuation">,</span> <span class="token number">0</span>	<span class="token comment">//写系统控制寄存器</span>

    <span class="token comment">/* enable fpu+neon 一些系统寄存器的操作
    | 使能浮点运算(floating point unit)和 NEON就是一种基于SIMD思想的ARM技术，相比于ARMv6或之前的架构，
    NEON结合了64-bit和128-bit的SIMD指令集，提供128-bit宽的向量运算(vector operations)*/</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifndef</span> <span class="token expression">LOSCFG_TEE_ENABLE        </span><span class="token comment">//Trusted Execution Environment   可信执行环境</span></span>
    MRC    p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r0<span class="token punctuation">,</span> c1<span class="token punctuation">,</span> c1<span class="token punctuation">,</span> <span class="token number">2</span> <span class="token comment">//非安全模式访问寄存器 (Non-Secure Access Control Register - NSACR)</span>
    ORR    r0<span class="token punctuation">,</span> r0<span class="token punctuation">,</span> #<span class="token number">0xC00</span>        <span class="token comment">//使能安全和非安全访问协处理器10和11(Coprocessor 10和11)</span>
    BIC    r0<span class="token punctuation">,</span> r0<span class="token punctuation">,</span> #<span class="token number">0xC000</span>       <span class="token comment">//设置bit15为0，不会影响修改CPACR.ASEDIS寄存器位（控制Advanced SIMD功能）| bit14 reserved</span>
    MCR    p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r0<span class="token punctuation">,</span> c1<span class="token punctuation">,</span> c1<span class="token punctuation">,</span> <span class="token number">2</span>

    LDR    r0<span class="token punctuation">,</span> <span class="token operator">=</span><span class="token punctuation">(</span><span class="token number">0xF</span> <span class="token operator">&lt;&lt;</span> <span class="token number">20</span><span class="token punctuation">)</span>      <span class="token comment">//允许在EL0和EL1下，访问协处理器10和11(控制Floating-point和Advanced SIMD特性)</span>
    MCR    p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r0<span class="token punctuation">,</span> c1<span class="token punctuation">,</span> c0<span class="token punctuation">,</span> <span class="token number">2</span>
    ISB
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>
    MOV    r3<span class="token punctuation">,</span> #<span class="token number">0x40000000</span>	    <span class="token comment">//EN, bit[30] 设置FPEXC的EN位来使能FPU</span>
    VMSR   FPEXC<span class="token punctuation">,</span> r3			<span class="token comment">//浮点异常控制寄存器 (Floating-Point Exception Control register | B4.1.57) </span>

    <span class="token comment">/* r11: delta of physical address and virtual address | 计算虚拟地址和物理地址之间的差值,目的是为了建立映射关系表 */</span>
    adr     r11<span class="token punctuation">,</span> pa_va_offset <span class="token comment">//获取pa_va_offset变量物理地址，由于这时候mmu已经被关闭，所以这个值就表示pa_va_offset变量的物理地址。</span>
                              <span class="token comment">/*adr 是一条小范围的地址读取伪指令,它将基于PC的相对偏移的地址值读到目标寄存器中。
                               *编译源程序时，汇编器首先计算当前PC值（当前指令位置）到exper的距离,然后用一条ADD或者SUB指令替换这条伪指令，
                               *例如:ADD register,PC,#offset_to_exper 注意，标号exper与指令必须在同一代码段
                               */</span>
    ldr     r0<span class="token punctuation">,</span> <span class="token punctuation">[</span>r11<span class="token punctuation">]</span>		  <span class="token comment">//r0 = *r11 获取pa_va_offset变量虚拟地址</span>
    sub     r11<span class="token punctuation">,</span> r11<span class="token punctuation">,</span> r0	  <span class="token comment">//物理地址-虚拟地址 = 映射偏移量 放入r11</span>

    mrc     p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r12<span class="token punctuation">,</span> c0<span class="token punctuation">,</span> c0<span class="token punctuation">,</span> <span class="token number">5</span>      <span class="token comment">/* Multiprocessor Affinity Register-MPIDR */</span>
    and     r12<span class="token punctuation">,</span> r12<span class="token punctuation">,</span> #MPIDR_CPUID_MASK <span class="token comment">//掩码过滤</span>
    cmp     r12<span class="token punctuation">,</span> #<span class="token number">0</span>	                    <span class="token comment">//主控核0判断</span>
    bne     secondary_cpu_init	        <span class="token comment">//初始化CPU次核</span>
	<span class="token comment">/*
	 * adr是小范围的地址读取伪指令,它将基于PC寄存器相对偏移的地址值读取到寄存器中，
	 * 例如: 0x00000004 	 : adr     r4, __exception_handlers
	 * 则此时PC寄存器的值为: 0x00000004 + 8(在三级流水线时,PC和执行地址相差8)，
     * adr指令和标识__exception_handlers的地址相对固定，二者偏移量若为offset,
	 * 最后r4 = (0x00000004 + 8) + offset
	*/</span>

    <span class="token comment">/* if we need to relocate to proper location or not | 如果需要重新安装到合适的位置*/</span>
    adr     r4<span class="token punctuation">,</span> __exception_handlers            <span class="token comment">/* r4: base of load address | 加载基址*/</span>
    ldr     r5<span class="token punctuation">,</span> <span class="token operator">=</span>SYS_MEM_BASE                   <span class="token comment">/* r5: base of physical address | 物理基址*/</span>
    subs    r12<span class="token punctuation">,</span> r4<span class="token punctuation">,</span> r5                         <span class="token comment">/* r12: delta of load address and physical address | 二者偏移量*/</span>
    beq     reloc_img_to_bottom_done            <span class="token comment">/* if we load image at the bottom of physical address | 不相等就需要重定位 */</span>
	
    <span class="token comment">/* we need to relocate image at the bottom of physical address | 需要知道拷贝的大小*/</span>
    ldr     r7<span class="token punctuation">,</span> <span class="token operator">=</span>__exception_handlers           <span class="token comment">/* r7: base of linked address (or vm address) | 链接地址基地址*/</span>
    ldr     r6<span class="token punctuation">,</span> <span class="token operator">=</span>__bss_start                    <span class="token comment">/* r6: end of linked address (or vm address)，由于目前阶段有用的数据是中断向量表+代码段+只读数据段+数据段，
											       所以只需复制[__exception_handlers,__bss_start]这段数据到内存基址处 */</span>
    sub     r6<span class="token punctuation">,</span> r7                              <span class="token comment">/* r6: delta of linked address (or vm address) | 内核镜像大小 */</span>
    add     r6<span class="token punctuation">,</span> r4                              <span class="token comment">/* r6: end of load address | 说明需拷贝[ r4,r4+r6 ] 区间内容到 [ r5,r5+r6 ]*/</span>

reloc_img_to_bottom_loop<span class="token operator">:</span><span class="token comment">//重定位镜像到内核物理内存基地址,将内核从加载地址拷贝到内存基址处</span>
    ldr     r7<span class="token punctuation">,</span> <span class="token punctuation">[</span>r4<span class="token punctuation">]</span><span class="token punctuation">,</span> #<span class="token number">4</span>	<span class="token comment">// 类似C语言 *r5 = *r4 , r4++ , r5++ </span>
    str     r7<span class="token punctuation">,</span> <span class="token punctuation">[</span>r5<span class="token punctuation">]</span><span class="token punctuation">,</span> #<span class="token number">4</span>	<span class="token comment">// #4 代表32位的指令长度,此时在拷贝内核代码区内容</span>
    cmp     r4<span class="token punctuation">,</span> r6          <span class="token comment">/* 拷贝完成条件. r4++ 直到等于r6 (加载结束地址) 完成拷贝动作 */</span>
    bne     reloc_img_to_bottom_loop
    sub     pc<span class="token punctuation">,</span> r12                             <span class="token comment">/* 重新校准pc寄存器, 无缝跳到了拷贝后的指令地址处执行 r12是重定位镜像前内核加载基地址和内核物理内存基地址的差值 */</span>
    nop		<span class="token comment">// 注意执行完成sub       pc, r12后,新的PC寄存器也指向了 	nop ,nop是伪汇编指令,等同于 mov r0 r0 通常用于控制时序的目的，强制内存对齐，防止流水线灾难，占据分支指令延迟						</span>
    sub     r11<span class="token punctuation">,</span> r11<span class="token punctuation">,</span> r12                       <span class="token comment">/* r11: eventual address offset | 最终地址映射偏移量, 用于构建MMU页表 */</span>
<span class="token comment">//内核总大小 __bss_start - __exception_handlers</span>
reloc_img_to_bottom_done<span class="token operator">:</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifdef</span> <span class="token expression">LOSCFG_KERNEL_MMU </span></span>
    ldr     r4<span class="token punctuation">,</span> <span class="token operator">=</span>g_firstPageTable               <span class="token comment">/* r4: physical address of translation table and clear it
												   内核页表是用数组g_firstPageTable存储 见于los_arch_mmu.c */</span>
    add     r4<span class="token punctuation">,</span> r4<span class="token punctuation">,</span> r11                         <span class="token comment">//计算g_firstPageTable页表物理地址</span>
    mov     r0<span class="token punctuation">,</span> r4								<span class="token comment">//因为默认r0 将作为memset_optimized的第一个参数</span>
    mov     r1<span class="token punctuation">,</span> #<span class="token number">0</span>								<span class="token comment">//第二个参数,清0</span>
    mov     r2<span class="token punctuation">,</span> #MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS <span class="token comment">//第三个参数是L1表的长度</span>
    bl      memset_optimized                    <span class="token comment">/* optimized memset since r0 is 64-byte aligned | 将内核页表空间清零*/</span>

    ldr     r5<span class="token punctuation">,</span> <span class="token operator">=</span>g_archMmuInitMapping	        <span class="token comment">//记录映射关系表</span>
    add     r5<span class="token punctuation">,</span> r5<span class="token punctuation">,</span> r11                         <span class="token comment">//获取g_archMmuInitMapping的物理地址</span>
init_mmu_loop<span class="token operator">:</span>	                                <span class="token comment">//初始化内核页表</span>
    ldmia   r5<span class="token operator">!</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>r6<span class="token operator">-</span>r10<span class="token punctuation">}</span>                       <span class="token comment">/* r6 = phys, r7 = virt, r8 = size, r9 = mmu_flags, r10 = name | 传参: 物理地址、虚拟地址、映射大小、映射属性、名称*/</span>
    cmp     r8<span class="token punctuation">,</span> <span class="token number">0</span>                               <span class="token comment">/* if size = 0, the mmu init done | 完成条件 */</span>
    beq     init_mmu_done		                <span class="token comment">//标志寄存器中Z标志位等于零时跳转到 	init_mmu_done处执行</span>
    bl      page_table_build	                <span class="token comment">//创建页表</span>
    b       init_mmu_loop						<span class="token comment">//循环继续</span>
init_mmu_done<span class="token operator">:</span>
    orr     r8<span class="token punctuation">,</span> r4<span class="token punctuation">,</span> #MMU_TTBRx_FLAGS            <span class="token comment">/* r8 = r4 and set cacheable attributes on translation walk | 设置缓存*/</span>
    ldr     r4<span class="token punctuation">,</span> <span class="token operator">=</span>g_mmuJumpPageTable             <span class="token comment">/* r4: jump pagetable vaddr | 页表虚拟地址*/</span>
    add     r4<span class="token punctuation">,</span> r4<span class="token punctuation">,</span> r11				
    ldr     r4<span class="token punctuation">,</span> <span class="token punctuation">[</span>r4<span class="token punctuation">]</span>
    add     r4<span class="token punctuation">,</span> r4<span class="token punctuation">,</span> r11                         <span class="token comment">/* r4: jump pagetable paddr | 页表物理地址*/</span>

    <span class="token comment">/* build 1M section mapping, in order to jump va during turing on mmu:pa == pa, va == pa */</span>
    <span class="token comment">/* 从当前PC开始建立1MB空间的段映射，分别建立物理地址和虚拟地址方式的段映射页表项
     * 内核临时页表在系统 使能mmu -&gt; 切换到虚拟地址运行 这段时间使用
     */</span>
    mov     r6<span class="token punctuation">,</span> pc
    mov     r7<span class="token punctuation">,</span> r6                              <span class="token comment">/* r7: pa (MB aligned)*/</span>
    lsr     r6<span class="token punctuation">,</span> r6<span class="token punctuation">,</span> #<span class="token number">20</span>                         <span class="token comment">/* r6: pa l1 index */</span>
    ldr     r10<span class="token punctuation">,</span> <span class="token operator">=</span>MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGS
    add     r12<span class="token punctuation">,</span> r10<span class="token punctuation">,</span> r6<span class="token punctuation">,</span> lsl #<span class="token number">20</span>               <span class="token comment">/* r12: pa |flags */</span>
    str     r12<span class="token punctuation">,</span> <span class="token punctuation">[</span>r4<span class="token punctuation">,</span> r7<span class="token punctuation">,</span> lsr #<span class="token punctuation">(</span><span class="token number">20</span> <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">]</span>        <span class="token comment">/* jumpTable[paIndex] = pt entry */</span>
    rsb     r7<span class="token punctuation">,</span> r11<span class="token punctuation">,</span> r6<span class="token punctuation">,</span> lsl #<span class="token number">20</span>                <span class="token comment">/* r7: va */</span>
    str     r12<span class="token punctuation">,</span> <span class="token punctuation">[</span>r4<span class="token punctuation">,</span> r7<span class="token punctuation">,</span> lsr #<span class="token punctuation">(</span><span class="token number">20</span> <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">]</span>        <span class="token comment">/* jumpTable[vaIndex] = pt entry */</span>

    bl      mmu_setup                           <span class="token comment">/* set up the mmu | 内核映射表已经创建好了,此时可以启动MMU工作了*/</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>
    <span class="token comment">/* clear out the interrupt and exception stack and set magic num to check the overflow 
    |exc_stack|地址高位
    |svc_stack|地址低位
	清除中断和异常堆栈并设置magic num检查溢出 */</span>
    ldr     r0<span class="token punctuation">,</span> <span class="token operator">=</span>__svc_stack	    <span class="token comment">//stack_init的第一个参数 __svc_stack表示栈顶</span>
    ldr     r1<span class="token punctuation">,</span> <span class="token operator">=</span>__exc_stack_top	<span class="token comment">//stack_init的第二个参数 __exc_stack_top表示栈底, 这里会有点绕, top表高地址位</span>
    bl      stack_init              <span class="token comment">//初始化各个cpu不同模式下的栈空间</span>
	<span class="token comment">//设置各个栈顶魔法数字</span>
    STACK_MAGIC_SET __svc_stack<span class="token punctuation">,</span> #OS_EXC_SVC_STACK_SIZE<span class="token punctuation">,</span> OS_STACK_MAGIC_WORD <span class="token comment">//中断栈底设成&quot;烫烫烫烫烫烫&quot;</span>
    STACK_MAGIC_SET __exc_stack<span class="token punctuation">,</span> #OS_EXC_STACK_SIZE<span class="token punctuation">,</span> OS_STACK_MAGIC_WORD     <span class="token comment">//异常栈底设成&quot;烫烫烫烫烫烫&quot;</span>

warm_reset<span class="token operator">:</span> <span class="token comment">//热启动 Warm Reset, warm reboot, soft reboot, 在不关闭电源的情况，由软件控制重启计算机</span>
    <span class="token comment">/* initialize CPSR (machine state register) */</span>
    mov    r0<span class="token punctuation">,</span> #<span class="token punctuation">(</span>CPSR_IRQ_DISABLE<span class="token operator">|</span>CPSR_FIQ_DISABLE<span class="token operator">|</span>CPSR_SVC_MODE<span class="token punctuation">)</span> <span class="token comment">/* 禁止IRQ中断 | 禁止FIQ中断 | 管理模式-操作系统使用的保护模式 */</span>
    msr    cpsr<span class="token punctuation">,</span> r0	<span class="token comment">//设置CPSR寄存器</span>

    <span class="token comment">/* Note: some functions in LIBGCC1 will cause a &quot;restore from SPSR&quot;!! */</span>
    msr    spsr<span class="token punctuation">,</span> r0 <span class="token comment">//设置SPSR寄存器</span>

    <span class="token comment">/* get cpuid and keep it in r12 */</span>
    mrc     p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r12<span class="token punctuation">,</span> c0<span class="token punctuation">,</span> c0<span class="token punctuation">,</span> <span class="token number">5</span>		<span class="token comment">//R12保存CPUID </span>
    and     r12<span class="token punctuation">,</span> r12<span class="token punctuation">,</span> #MPIDR_CPUID_MASK <span class="token comment">//掩码操作获取当前cpu id</span>

    <span class="token comment">/* set svc stack, every cpu has OS_EXC_SVC_STACK_SIZE stack | 设置 SVC栈 */</span>
    ldr    r0<span class="token punctuation">,</span> <span class="token operator">=</span>__svc_stack_top <span class="token comment">//注意这是栈底,高地址位</span>
    mov    r2<span class="token punctuation">,</span> #OS_EXC_SVC_STACK_SIZE <span class="token comment">//栈大小</span>
    mul    r2<span class="token punctuation">,</span> r2<span class="token punctuation">,</span> r12 
    sub    r0<span class="token punctuation">,</span> r0<span class="token punctuation">,</span> r2                   <span class="token comment">/* 算出当前core的中断栈栈顶位置，写入所属core的sp */</span>
    mov    sp<span class="token punctuation">,</span> r0

    LDR    r0<span class="token punctuation">,</span> <span class="token operator">=</span>__exception_handlers    
    MCR    p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r0<span class="token punctuation">,</span> c12<span class="token punctuation">,</span> c0<span class="token punctuation">,</span> <span class="token number">0</span>       <span class="token comment">/* Vector Base Address Register - VBAR */</span>

    cmp    r12<span class="token punctuation">,</span> #<span class="token number">0</span>						<span class="token comment">//CPU是否为主核</span>
    bne    cpu_start                    <span class="token comment">//不相等就跳到从核处理分支</span>

clear_bss<span class="token operator">:</span>	                            <span class="token comment">//主核处理.bss段清零</span>
    ldr    r0<span class="token punctuation">,</span> <span class="token operator">=</span>__bss_start
    ldr    r2<span class="token punctuation">,</span> <span class="token operator">=</span>__bss_end
    mov    r1<span class="token punctuation">,</span> #<span class="token number">0</span>
    sub    r2<span class="token punctuation">,</span> r2<span class="token punctuation">,</span> r0
    bl     memset
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">if</span> <span class="token expression"><span class="token function">defined</span><span class="token punctuation">(</span>LOSCFG_CC_STACKPROTECTOR_ALL<span class="token punctuation">)</span> <span class="token operator">||</span> </span><span class="token punctuation">\</span>
    <span class="token expression"><span class="token function">defined</span><span class="token punctuation">(</span>LOSCFG_CC_STACKPROTECTOR_STRONG<span class="token punctuation">)</span> <span class="token operator">||</span> </span><span class="token punctuation">\</span>
    <span class="token expression"><span class="token function">defined</span><span class="token punctuation">(</span>LOSCFG_CC_STACKPROTECTOR<span class="token punctuation">)</span></span></span>
    bl     __stack_chk_guard_setup
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>

<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifdef</span> <span class="token expression">LOSCFG_GDB_DEBUG</span></span>
    <span class="token comment">/* GDB_START - generate a compiled_breadk,This function will get GDB stubs started, with a proper environment */</span>
    bl     GDB_START
    <span class="token punctuation">.</span>word  <span class="token number">0xe7ffdeff</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>

    bl     main                <span class="token comment">//带LR的子程序跳转, LR = pc - 4, 执行C层main函数    </span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br><span class="line-number">57</span><br><span class="line-number">58</span><br><span class="line-number">59</span><br><span class="line-number">60</span><br><span class="line-number">61</span><br><span class="line-number">62</span><br><span class="line-number">63</span><br><span class="line-number">64</span><br><span class="line-number">65</span><br><span class="line-number">66</span><br><span class="line-number">67</span><br><span class="line-number">68</span><br><span class="line-number">69</span><br><span class="line-number">70</span><br><span class="line-number">71</span><br><span class="line-number">72</span><br><span class="line-number">73</span><br><span class="line-number">74</span><br><span class="line-number">75</span><br><span class="line-number">76</span><br><span class="line-number">77</span><br><span class="line-number">78</span><br><span class="line-number">79</span><br><span class="line-number">80</span><br><span class="line-number">81</span><br><span class="line-number">82</span><br><span class="line-number">83</span><br><span class="line-number">84</span><br><span class="line-number">85</span><br><span class="line-number">86</span><br><span class="line-number">87</span><br><span class="line-number">88</span><br><span class="line-number">89</span><br><span class="line-number">90</span><br><span class="line-number">91</span><br><span class="line-number">92</span><br><span class="line-number">93</span><br><span class="line-number">94</span><br><span class="line-number">95</span><br><span class="line-number">96</span><br><span class="line-number">97</span><br><span class="line-number">98</span><br><span class="line-number">99</span><br><span class="line-number">100</span><br><span class="line-number">101</span><br><span class="line-number">102</span><br><span class="line-number">103</span><br><span class="line-number">104</span><br><span class="line-number">105</span><br><span class="line-number">106</span><br><span class="line-number">107</span><br><span class="line-number">108</span><br><span class="line-number">109</span><br><span class="line-number">110</span><br><span class="line-number">111</span><br><span class="line-number">112</span><br><span class="line-number">113</span><br><span class="line-number">114</span><br><span class="line-number">115</span><br><span class="line-number">116</span><br><span class="line-number">117</span><br><span class="line-number">118</span><br><span class="line-number">119</span><br><span class="line-number">120</span><br><span class="line-number">121</span><br><span class="line-number">122</span><br><span class="line-number">123</span><br><span class="line-number">124</span><br><span class="line-number">125</span><br><span class="line-number">126</span><br><span class="line-number">127</span><br><span class="line-number">128</span><br><span class="line-number">129</span><br><span class="line-number">130</span><br><span class="line-number">131</span><br><span class="line-number">132</span><br><span class="line-number">133</span><br><span class="line-number">134</span><br><span class="line-number">135</span><br><span class="line-number">136</span><br><span class="line-number">137</span><br><span class="line-number">138</span><br><span class="line-number">139</span><br><span class="line-number">140</span><br><span class="line-number">141</span><br><span class="line-number">142</span><br><span class="line-number">143</span><br><span class="line-number">144</span><br><span class="line-number">145</span><br><span class="line-number">146</span><br><span class="line-number">147</span><br><span class="line-number">148</span><br><span class="line-number">149</span><br><span class="line-number">150</span><br><span class="line-number">151</span><br><span class="line-number">152</span><br><span class="line-number">153</span><br><span class="line-number">154</span><br><span class="line-number">155</span><br><span class="line-number">156</span><br><span class="line-number">157</span><br><span class="line-number">158</span><br><span class="line-number">159</span><br><span class="line-number">160</span><br><span class="line-number">161</span><br><span class="line-number">162</span><br><span class="line-number">163</span><br><span class="line-number">164</span><br></div></div><p><strong>解读</strong></p> <ul><li><p><strong>第一步：</strong> 操作 <strong>CP15</strong> 协处理器 <strong>TPIDRPRW</strong> 寄存器，它被 <strong>ARM</strong> 设计保存当前运行线程的 <strong>ID</strong>值，在<strong>ARMv7</strong> 架构中才新出现，需<strong>PL1</strong>权限以上才能访问，而硬件不会从内部去改变它的值，也就是说这是一个直接暴露给工程师操作维护的一个寄存器，在鸿蒙内核中被用于记录线程结构体的开始地址，可以搜索 <strong>OsCurrTaskSet</strong> 来跟踪哪些地方会切换当前任务以便更好的理解内核。</p></li> <li><p><strong>第二步：</strong> 系统控制寄存器（<strong>SCTLR</strong>），<strong>B4.1.130 SCTLR, System Control Register</strong>  它提供了系统的最高级别控制，高到了玉皇大帝级别，代码中将 <code>0</code>、<code>2</code>、<code>12</code>位写 <code>0</code>。对应关闭 <strong>MMU</strong> 、<strong>数据缓存</strong> 、<strong>指令缓存</strong> 功能。</p></li> <li><p><strong>第三步：</strong> 对浮点运算<code>FPU</code>的设置，在安全模式下使用<code>FPU</code>，须定义<code>NSACR</code>、<code>CPACR</code>、<code>FPEXC</code> 三个寄存器</p></li> <li><p><strong>第四步：</strong> 计算虚拟地址和物理地址的偏移量，为何要计算它呢 ? 唯一目的是为了建立虚拟地址和物理地址的映射关系，因为在 MMU启动之后，运行地址(PC寄存器指向的地址)被CPU理解成虚拟地址，使用虚拟地址就离不开映射表，所以两个地址的映射关系需要在MMU启动前就创建好，而有了偏移量就可以创建映射表。但需先搞清楚 <strong>链接地址</strong> 和 <strong>运行地址</strong> 两个概念。</p> <ul><li><strong>链接地址</strong> 由链接器确定，链接器会将所有输入的 <strong>.o</strong> 文件链接成一个 <strong>.bin</strong> 文件，它们都是<strong>ELF</strong>格式, 链接器给每条指令/数据都赋与一个地址，这个地址叫<strong>链接地址</strong>，它可以是相对的也可以是绝对的。但它们之间的内部距离是固定的，链接具体过程可翻看 <strong>(重定位篇)</strong> 和 <strong>(链接脚本篇)</strong>。</li> <li><strong>运行地址</strong> 由加载器确定，内核镜像首先通过烧录工具将内核烧录到 <strong>flash</strong> 指定的位置，开机后由<strong>boot loader</strong>工具，例如<strong>uboot</strong>，将内核镜像加载到指定地址后开始执行真正的内核代码，这个地址叫<strong>运行地址</strong>。</li></ul> <p>两个地址值往往不一样，而内核设计者希望它们是一样的，那有没有办法检测二者是否一样呢?答案是： <strong>有，那必须的</strong> 。通过一个变量在链接时将其链接地址变成变量的内容 ，无论中间怎么加载变量的内容是不会变的，而获取运行地址是很容易获取的，其实就是PC寄存器的地址，二者相减，加载后偏了多少可不就出来了。别看说了这么一大串，实现却只需4行代码，但如果没有上面的废话每一行都会把您整懵逼。</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code>pa_va_offset<span class="token operator">:</span>	
  <span class="token punctuation">.</span>word   <span class="token punctuation">.</span> <span class="token comment">//定义一个4字节的pa_va_offset 变量， 链接器生成一个链接地址， . 表示 pa_va_offset = 链接地址 举例: 在地址 0x17321796 中保存了 0x17321796 值</span>

adr     r11<span class="token punctuation">,</span> pa_va_offset <span class="token comment">//代码已执行至此，指令将获取 pa_va_offset 的运行地址(可能不是`0x17321796`) 给r11</span>
ldr     r0<span class="token punctuation">,</span> <span class="token punctuation">[</span>r11<span class="token punctuation">]</span> <span class="token comment">// [r11]中存的是链接地址 `0x17321796`, 它不会随加载器变化的</span>
sub     r11<span class="token punctuation">,</span> r11<span class="token punctuation">,</span> r0 <span class="token comment">// 二者相减得到了偏移地址</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div></li> <li><p><strong>第五步：</strong> 将内核代码从 <strong>__exception_handlers</strong> 处移到 <strong>SYS_MEM_BASE</strong>处,长度是 <strong>__bss_start  -  __exception_handlers</strong> , <strong>__exception_handlers</strong>是加载后的开始地址, 由加载器决定, 而<strong>SYS_MEM_BASE</strong> 是系统定义的内存地址, 可由系统集成商指定配置, 他们希望内核从这里运行。 下图为内核镜像布局
<img src="https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/78/bbs.png" alt=""></p> <p>具体代码如下:</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code>    <span class="token comment">/* if we need to relocate to proper location or not | 如果需要重新安装到合适的位置*/</span>
  adr     r4<span class="token punctuation">,</span> __exception_handlers            <span class="token comment">/* r4: base of load address | 加载基址*/</span>
  ldr     r5<span class="token punctuation">,</span> <span class="token operator">=</span>SYS_MEM_BASE                   <span class="token comment">/* r5: base of physical address | 物理基址*/</span>
  subs    r12<span class="token punctuation">,</span> r4<span class="token punctuation">,</span> r5                         <span class="token comment">/* r12: delta of load address and physical address | 二者偏移量*/</span>
  beq     reloc_img_to_bottom_done            <span class="token comment">/* if we load image at the bottom of physical address | 不相等就需要重定位 */</span>
  
  <span class="token comment">/* we need to relocate image at the bottom of physical address | 需要知道拷贝的大小*/</span>
  ldr     r7<span class="token punctuation">,</span> <span class="token operator">=</span>__exception_handlers           <span class="token comment">/* r7: base of linked address (or vm address) | 链接地址基地址*/</span>
  ldr     r6<span class="token punctuation">,</span> <span class="token operator">=</span>__bss_start                    <span class="token comment">/* r6: end of linked address (or vm address)，由于目前阶段有用的数据是中断向量表+代码段+只读数据段+数据段，
  										       所以只需复制[__exception_handlers,__bss_start]这段数据到内存基址处 */</span>
  sub     r6<span class="token punctuation">,</span> r7                              <span class="token comment">/* r6: delta of linked address (or vm address) | 内核镜像大小 */</span>
  add     r6<span class="token punctuation">,</span> r4                              <span class="token comment">/* r6: end of load address | 说明需拷贝[ r4,r4+r6 ] 区间内容到 [ r5,r5+r6 ]*/</span>

  reloc_img_to_bottom_loop<span class="token operator">:</span><span class="token comment">//重定位镜像到内核物理内存基地址,将内核从加载地址拷贝到内存基址处</span>
      ldr     r7<span class="token punctuation">,</span> <span class="token punctuation">[</span>r4<span class="token punctuation">]</span><span class="token punctuation">,</span> #<span class="token number">4</span>	<span class="token comment">// 类似C语言 *r5 = *r4 , r4++ , r5++ </span>
      str     r7<span class="token punctuation">,</span> <span class="token punctuation">[</span>r5<span class="token punctuation">]</span><span class="token punctuation">,</span> #<span class="token number">4</span>	<span class="token comment">// #4 代表32位的指令长度,此时在拷贝内核代码区内容</span>
      cmp     r4<span class="token punctuation">,</span> r6          <span class="token comment">/* 拷贝完成条件. r4++ 直到等于r6 (加载结束地址) 完成拷贝动作 */</span>
      bne     reloc_img_to_bottom_loop
      sub     pc<span class="token punctuation">,</span> r12                             <span class="token comment">/* 重新校准pc寄存器, 无缝跳到了拷贝后的指令地址处执行 r12是重定位镜像前内核加载基地址和内核物理内存基地址的差值 */</span>
      nop		<span class="token comment">// 注意执行完成sub       pc, r12后,新的PC寄存器也指向了 	nop ,nop是伪汇编指令,等同于 mov r0 r0 通常用于控制时序的目的，强制内存对齐，防止流水线灾难，占据分支指令延迟						</span>
      sub     r11<span class="token punctuation">,</span> r11<span class="token punctuation">,</span> r12                       <span class="token comment">/* r11: eventual address offset | 最终地址偏移量 */</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br></div></div></li> <li><p><strong>第六步：</strong> 在打开MMU必须要做好虚拟地址和物理地址的映射关系 , 需构建页表 , 关于页表可翻看 <strong>虚实映射篇</strong>, 具体代码如下</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifdef</span> <span class="token expression">LOSCFG_KERNEL_MMU </span></span>
ldr     r4<span class="token punctuation">,</span> <span class="token operator">=</span>g_firstPageTable               <span class="token comment">/* r4: physical address of translation table and clear it
											   内核页表是用数组g_firstPageTable存储 见于los_arch_mmu.c */</span>
add     r4<span class="token punctuation">,</span> r4<span class="token punctuation">,</span> r11                         <span class="token comment">//计算g_firstPageTable页表物理地址</span>
mov     r0<span class="token punctuation">,</span> r4								<span class="token comment">//因为默认r0 将作为memset_optimized的第一个参数</span>
mov     r1<span class="token punctuation">,</span> #<span class="token number">0</span>								<span class="token comment">//第二个参数,清0</span>
mov     r2<span class="token punctuation">,</span> #MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS <span class="token comment">//第三个参数是L1表的长度</span>
bl      memset_optimized                    <span class="token comment">/* optimized memset since r0 is 64-byte aligned | 将内核页表空间清零*/</span>

ldr     r5<span class="token punctuation">,</span> <span class="token operator">=</span>g_archMmuInitMapping	        <span class="token comment">//记录映射关系表</span>
add     r5<span class="token punctuation">,</span> r5<span class="token punctuation">,</span> r11                         <span class="token comment">//获取g_archMmuInitMapping的物理地址</span>
init_mmu_loop<span class="token operator">:</span>	                                <span class="token comment">//初始化内核页表</span>
    ldmia   r5<span class="token operator">!</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>r6<span class="token operator">-</span>r10<span class="token punctuation">}</span>                       <span class="token comment">/* r6 = phys, r7 = virt, r8 = size, r9 = mmu_flags, r10 = name | 物理地址、虚拟地址、映射大小、映射属性、名称*/</span>
    cmp     r8<span class="token punctuation">,</span> <span class="token number">0</span>                               <span class="token comment">/* if size = 0, the mmu init done */</span>
    beq     init_mmu_done		                <span class="token comment">//标志寄存器中Z标志位等于零时跳转到 	init_mmu_done处执行</span>
    bl      page_table_build	                <span class="token comment">//创建页表</span>
    b       init_mmu_loop						<span class="token comment">//循环继续</span>
init_mmu_done<span class="token operator">:</span>
    orr     r8<span class="token punctuation">,</span> r4<span class="token punctuation">,</span> #MMU_TTBRx_FLAGS            <span class="token comment">/* r8 = r4 and set cacheable attributes on translation walk | 设置缓存*/</span>
    ldr     r4<span class="token punctuation">,</span> <span class="token operator">=</span>g_mmuJumpPageTable             <span class="token comment">/* r4: jump pagetable vaddr | 页表虚拟地址*/</span>
    add     r4<span class="token punctuation">,</span> r4<span class="token punctuation">,</span> r11				
    ldr     r4<span class="token punctuation">,</span> <span class="token punctuation">[</span>r4<span class="token punctuation">]</span>
    add     r4<span class="token punctuation">,</span> r4<span class="token punctuation">,</span> r11                         <span class="token comment">/* r4: jump pagetable paddr | 页表物理地址*/</span>

    <span class="token comment">/* build 1M section mapping, in order to jump va during turing on mmu:pa == pa, va == pa */</span>
    <span class="token comment">/* 从当前PC开始建立1MB空间的段映射，分别建立物理地址和虚拟地址方式的段映射页表项
    * 内核临时页表在系统 使能mmu -&gt; 切换到虚拟地址运行 这段时间使用
    */</span>
    mov     r6<span class="token punctuation">,</span> pc
    mov     r7<span class="token punctuation">,</span> r6                              <span class="token comment">/* r7: pa (MB aligned)*/</span>
    lsr     r6<span class="token punctuation">,</span> r6<span class="token punctuation">,</span> #<span class="token number">20</span>                         <span class="token comment">/* r6: pa l1 index */</span>
    ldr     r10<span class="token punctuation">,</span> <span class="token operator">=</span>MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGS
    add     r12<span class="token punctuation">,</span> r10<span class="token punctuation">,</span> r6<span class="token punctuation">,</span> lsl #<span class="token number">20</span>               <span class="token comment">/* r12: pa |flags */</span>
    str     r12<span class="token punctuation">,</span> <span class="token punctuation">[</span>r4<span class="token punctuation">,</span> r7<span class="token punctuation">,</span> lsr #<span class="token punctuation">(</span><span class="token number">20</span> <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">]</span>        <span class="token comment">/* jumpTable[paIndex] = pt entry */</span>
    rsb     r7<span class="token punctuation">,</span> r11<span class="token punctuation">,</span> r6<span class="token punctuation">,</span> lsl #<span class="token number">20</span>                <span class="token comment">/* r7: va */</span>
    str     r12<span class="token punctuation">,</span> <span class="token punctuation">[</span>r4<span class="token punctuation">,</span> r7<span class="token punctuation">,</span> lsr #<span class="token punctuation">(</span><span class="token number">20</span> <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">]</span>        <span class="token comment">/* jumpTable[vaIndex] = pt entry */</span>

    bl      mmu_setup                           <span class="token comment">/* set up the mmu | 内核映射表已经创建好了,此时可以启动MMU工作了*/</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br></div></div></li> <li><p><strong>第七步：</strong> 使能MMU, 有了页表就可以使用虚拟地址了</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code>mmu_setup<span class="token operator">:</span>	<span class="token comment">//启动MMU工作</span>
    mov     r12<span class="token punctuation">,</span> #<span class="token number">0</span>                             <span class="token comment">/* TLB Invalidate All entries - TLBIALL */</span>
    mcr     p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r12<span class="token punctuation">,</span> c8<span class="token punctuation">,</span> c7<span class="token punctuation">,</span> <span class="token number">0</span>              <span class="token comment">/* Set c8 to control the TLB and set the mapping to invalid */</span>
    isb
    mcr     p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r12<span class="token punctuation">,</span> c2<span class="token punctuation">,</span> c0<span class="token punctuation">,</span> <span class="token number">2</span>              <span class="token comment">/* Translation Table Base Control Register(TTBCR) = 0x0
                                                [31] :0 - Use the 32-bit translation system(虚拟地址是32位)
                                                [5:4]:0 - use TTBR0和TTBR1
                                                [2:0]:0 - TTBCR.N为0；
                                                例如：TTBCR.N为0，TTBR0[31:14-0] | VA[31-0:20] | descriptor-type[1:0]组成32位页表描述符的地址,
                                                        VA[31:20]可以覆盖4GB的地址空间，所以TTBR0页表是16KB，不使用TTBR1;
                                                例如：TTBCR.N为1，TTBR0[31:14-1] | VA[31-1:20] | descriptor-type[1:0]组成32位页表描述符的地址,
                                                        VA[30:20]可以覆盖2GB的地址空间，所以TTBR0页表是8KB，TTBR1页表是8KB(页表地址必须16KB对齐);
                                                */</span>
    isb
    orr     r12<span class="token punctuation">,</span> r4<span class="token punctuation">,</span> #MMU_TTBRx_FLAGS			<span class="token comment">//将临时页表属性[6:0]和基地址[31:14]放到r12</span>
    mcr     p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r12<span class="token punctuation">,</span> c2<span class="token punctuation">,</span> c0<span class="token punctuation">,</span> <span class="token number">0</span>              <span class="token comment">/* Set attributes and set temp page table */</span>
    isb
    mov     r12<span class="token punctuation">,</span> #<span class="token number">0x7</span>                           <span class="token comment">/* 0b0111 */</span>
    mcr     p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r12<span class="token punctuation">,</span> c3<span class="token punctuation">,</span> c0<span class="token punctuation">,</span> <span class="token number">0</span>              <span class="token comment">/* Set DACR with 0b0111, client and manager domian */</span>
    isb
    mrc    p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r12<span class="token punctuation">,</span> c1<span class="token punctuation">,</span> c0<span class="token punctuation">,</span> <span class="token number">1</span>               <span class="token comment">/* ACTLR, Auxlliary Control Register */</span>
    orr    r12<span class="token punctuation">,</span> r12<span class="token punctuation">,</span> #<span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">&lt;&lt;</span> <span class="token number">6</span><span class="token punctuation">)</span>                  <span class="token comment">/* SMP, Enables coherent requests to the processor. */</span>
    orr    r12<span class="token punctuation">,</span> r12<span class="token punctuation">,</span> #<span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">&lt;&lt;</span> <span class="token number">2</span><span class="token punctuation">)</span>                  <span class="token comment">/* Enable D-side prefetch */</span>
    orr    r12<span class="token punctuation">,</span> r12<span class="token punctuation">,</span> #<span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">&lt;&lt;</span> <span class="token number">11</span><span class="token punctuation">)</span>                 <span class="token comment">/* Global BP Enable bit */</span>
    mcr    p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r12<span class="token punctuation">,</span> c1<span class="token punctuation">,</span> c0<span class="token punctuation">,</span> <span class="token number">1</span>               <span class="token comment">/* ACTLR, Auxlliary Control Register */</span>
    dsb
    <span class="token comment">/*
    * 开始使能MMU，使用的是内核临时页表，这时cpu访问内存不管是取指令还是访问数据都是需要经过mmu来翻译，
    * 但是在mmu使能之前cpu使用的都是内核的物理地址，即使现在使能了mmu，cpu访问的地址值还是内核的物理地址值(这里仅仅从数值上来看)，
    * 而又由于mmu使能了，所以cpu会把这个值当做虚拟地址的值到页表中去找其对应的物理地址来访问。
    * 所以现在明白了为什么要在内核临时页表里建立一个内核物理地址和虚拟地址一一映射的页表项了吧，因为建立了一一映射，
    * cpu访问的地址经过mmu翻译得到的还是和原来一样的值，这样在cpu真正使用虚拟地址之前也能正常运行。
    */</span>
    mrc     p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r12<span class="token punctuation">,</span> c1<span class="token punctuation">,</span> c0<span class="token punctuation">,</span> <span class="token number">0</span>
    bic     r12<span class="token punctuation">,</span> #<span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">&lt;&lt;</span> <span class="token number">29</span> <span class="token operator">|</span> <span class="token number">1</span> <span class="token operator">&lt;&lt;</span> <span class="token number">28</span><span class="token punctuation">)</span>           <span class="token comment">/* disable access flag[bit29]，ap[0]是访问权限位，支持全部的访问权限类型
                                                disable TEX remap[bit28]，使用TEX[2:0]与C Bbit控制memory region属性 */</span>
    orr     r12<span class="token punctuation">,</span> #<span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">&lt;&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>                      <span class="token comment">/* mmu enable */</span>
    bic     r12<span class="token punctuation">,</span> #<span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">&lt;&lt;</span> <span class="token number">1</span><span class="token punctuation">)</span>
    orr     r12<span class="token punctuation">,</span> #<span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">&lt;&lt;</span> <span class="token number">2</span><span class="token punctuation">)</span>                     <span class="token comment">/* D cache enable */</span>
    orr     r12<span class="token punctuation">,</span> #<span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">&lt;&lt;</span> <span class="token number">12</span><span class="token punctuation">)</span>                    <span class="token comment">/* I cache enable */</span>
    mcr     p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r12<span class="token punctuation">,</span> c1<span class="token punctuation">,</span> c0<span class="token punctuation">,</span> <span class="token number">0</span>              <span class="token comment">/* Set SCTLR with r12: Turn on the MMU, I/D cache Disable TRE/AFE */</span>
    isb
    ldr     pc<span class="token punctuation">,</span>  <span class="token operator">=</span><span class="token number">1f</span>                            <span class="token comment">/* Convert to VA | 1表示标号，f表示forward(往下) - pc值取往下标识符“1”的虚拟地址(跳转到标识符“1”处)
                                                因为之前已经在内核临时页表中建立了内核虚拟地址和物理地址的映射关系，所以接下来cpu切换到虚拟地址空间 */</span>
    <span class="token number">1</span><span class="token operator">:</span>
        mcr     p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r8<span class="token punctuation">,</span> c2<span class="token punctuation">,</span> c0<span class="token punctuation">,</span> <span class="token number">0</span>               <span class="token comment">/* Go to the base address saved in C2: Jump to the page table */</span>
        isb                                         <span class="token comment">//r8中保存的是内核L1页表基地址和flags，r8写入到TTBR0实现临时页表和内核页表的切换</span>
        mov     r12<span class="token punctuation">,</span> #<span class="token number">0</span>
        mcr     p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r12<span class="token punctuation">,</span> c8<span class="token punctuation">,</span> c7<span class="token punctuation">,</span> <span class="token number">0</span>              <span class="token comment">/* TLB Invalidate All entries - TLBIALL(Invalidate all EL1&amp;0 regime stage 1 and 2 TLB entries) */</span>
        isb
        sub     lr<span class="token punctuation">,</span>  r11                            <span class="token comment">/* adjust lr with delta of physical address and virtual address | 
                                                    lr中保存的是mmu使能之前返回地址的物理地址值，这时需要转换为虚拟地址，转换算法也很简单，虚拟地址 = 物理地址 - r11 */</span>
        bx      lr                                  <span class="token comment">//返回</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br></div></div></li> <li><p><strong>第八步：</strong> 设置异常和中断栈 ，初始化栈内值和栈顶值</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token comment">//初始化栈内值</span>
    ldr     r0<span class="token punctuation">,</span> <span class="token operator">=</span>__svc_stack	    <span class="token comment">//stack_init的第一个参数 __svc_stack表示栈顶</span>
    ldr     r1<span class="token punctuation">,</span> <span class="token operator">=</span>__exc_stack_top	<span class="token comment">//stack_init的第二个参数 __exc_stack_top表示栈底, 这里会有点绕, top表高地址位</span>
    bl      stack_init              <span class="token comment">//初始化各个cpu不同模式下的栈空间</span>
    <span class="token comment">//设置各个栈顶魔法数字</span>
    STACK_MAGIC_SET __svc_stack<span class="token punctuation">,</span> #OS_EXC_SVC_STACK_SIZE<span class="token punctuation">,</span> OS_STACK_MAGIC_WORD <span class="token comment">//中断栈底设成&quot;烫烫烫烫烫烫&quot;</span>
    STACK_MAGIC_SET __exc_stack<span class="token punctuation">,</span> #OS_EXC_STACK_SIZE<span class="token punctuation">,</span> OS_STACK_MAGIC_WORD     <span class="token comment">//异常栈底设成&quot;烫烫烫烫烫烫&quot;</span>
stack_init<span class="token operator">:</span>
    ldr     r2<span class="token punctuation">,</span> <span class="token operator">=</span>OS_STACK_INIT	<span class="token comment">//0xCACACACA</span>
    ldr     r3<span class="token punctuation">,</span> <span class="token operator">=</span>OS_STACK_INIT
    <span class="token comment">/* Main loop sets 32 bytes at a time. | 主循环一次设置 32 个字节*/</span>
stack_init_loop<span class="token operator">:</span>
    <span class="token punctuation">.</span>irp    offset<span class="token punctuation">,</span> #<span class="token number">0</span><span class="token punctuation">,</span> #<span class="token number">8</span><span class="token punctuation">,</span> #<span class="token number">16</span><span class="token punctuation">,</span> #<span class="token number">24</span>
    strd    r2<span class="token punctuation">,</span> r3<span class="token punctuation">,</span> <span class="token punctuation">[</span>r0<span class="token punctuation">,</span> \offset<span class="token punctuation">]</span>    <span class="token comment">/* 等价于strd r2, r3, [r0, 0], strd r2, r3, [r0, 8], ... , strd r2, r3, [r0, 24] */</span>
    <span class="token punctuation">.</span>endr
    add     r0<span class="token punctuation">,</span> #<span class="token number">32</span>			<span class="token comment">//加跳32个字节,说明在地址范围上 r1 &gt; r0 ==&gt; __exc_stack_top &gt; __svc_stack</span>
    cmp     r0<span class="token punctuation">,</span> r1			<span class="token comment">//是否到栈底</span>
    blt     stack_init_loop
    bx      lr

</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br></div></div><div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token comment">//初始化栈顶值</span>
excstack_magic<span class="token operator">:</span>
    mov     r3<span class="token punctuation">,</span> #<span class="token number">0</span> <span class="token comment">//r3 = 0</span>
excstack_magic_loop<span class="token operator">:</span>
    str     r2<span class="token punctuation">,</span> <span class="token punctuation">[</span>r0<span class="token punctuation">]</span>   <span class="token comment">//栈顶设置魔法数字</span>
    add     r0<span class="token punctuation">,</span> r0<span class="token punctuation">,</span> r1 <span class="token comment">//定位到栈底</span>
    add     r3<span class="token punctuation">,</span> r3<span class="token punctuation">,</span> #<span class="token number">1</span> <span class="token comment">//r3++</span>
    cmp     r3<span class="token punctuation">,</span> #CORE_NUM <span class="token comment">//栈空间等分成core_num个空间，所以每个core的栈顶需要magic num</span>
    blt     excstack_magic_loop
    bx      lr
<span class="token comment">/* param0 is stack top, param1 is stack size, param2 is magic num */</span>
<span class="token punctuation">.</span>macro STACK_MAGIC_SET param0<span class="token punctuation">,</span> param1<span class="token punctuation">,</span> param2
    ldr     r0<span class="token punctuation">,</span> <span class="token operator">=</span>\param0
    mov     r1<span class="token punctuation">,</span> \param1
    ldr     r2<span class="token punctuation">,</span> <span class="token operator">=</span>\param2
    bl      excstack_magic
<span class="token punctuation">.</span>endm
STACK_MAGIC_SET __svc_stack<span class="token punctuation">,</span> #OS_EXC_SVC_STACK_SIZE<span class="token punctuation">,</span> OS_STACK_MAGIC_WORD <span class="token comment">//中断栈底设成&quot;烫烫烫烫烫烫&quot;</span>
STACK_MAGIC_SET __exc_stack<span class="token punctuation">,</span> #OS_EXC_STACK_SIZE<span class="token punctuation">,</span> OS_STACK_MAGIC_WORD     <span class="token comment">//异常栈底设成&quot;烫烫烫烫烫烫&quot;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br></div></div></li> <li><p><strong>第九步：</strong>  热启动</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code>warm_reset<span class="token operator">:</span> <span class="token comment">//热启动 Warm Reset, warm reboot, soft reboot, 在不关闭电源的情况，由软件控制重启计算机</span>
  <span class="token comment">/* initialize CPSR (machine state register) */</span>
  mov    r0<span class="token punctuation">,</span> #<span class="token punctuation">(</span>CPSR_IRQ_DISABLE<span class="token operator">|</span>CPSR_FIQ_DISABLE<span class="token operator">|</span>CPSR_SVC_MODE<span class="token punctuation">)</span> <span class="token comment">/* 禁止IRQ中断 | 禁止FIQ中断 | 管理模式-操作系统使用的保护模式 */</span>
  msr    cpsr<span class="token punctuation">,</span> r0

  <span class="token comment">/* Note: some functions in LIBGCC1 will cause a &quot;restore from SPSR&quot;!! */</span>
  msr    spsr<span class="token punctuation">,</span> r0

  <span class="token comment">/* get cpuid and keep it in r12 */</span>
  mrc     p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r12<span class="token punctuation">,</span> c0<span class="token punctuation">,</span> c0<span class="token punctuation">,</span> <span class="token number">5</span>		<span class="token comment">//R12保存CPUID </span>
  and     r12<span class="token punctuation">,</span> r12<span class="token punctuation">,</span> #MPIDR_CPUID_MASK <span class="token comment">//掩码操作获取当前cpu id</span>

  <span class="token comment">/* set svc stack, every cpu has OS_EXC_SVC_STACK_SIZE stack */</span>
  ldr    r0<span class="token punctuation">,</span> <span class="token operator">=</span>__svc_stack_top
  mov    r2<span class="token punctuation">,</span> #OS_EXC_SVC_STACK_SIZE
  mul    r2<span class="token punctuation">,</span> r2<span class="token punctuation">,</span> r12
  sub    r0<span class="token punctuation">,</span> r0<span class="token punctuation">,</span> r2                   <span class="token comment">/* 算出当前core的中断栈栈顶位置，写入所属core的sp */</span>
  mov    sp<span class="token punctuation">,</span> r0

  LDR    r0<span class="token punctuation">,</span> <span class="token operator">=</span>__exception_handlers
  MCR    p15<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> r0<span class="token punctuation">,</span> c12<span class="token punctuation">,</span> c0<span class="token punctuation">,</span> <span class="token number">0</span>       <span class="token comment">/* Vector Base Address Register - VBAR */</span>

  cmp    r12<span class="token punctuation">,</span> #<span class="token number">0</span>
  bne    cpu_start                    <span class="token comment">//从核处理分支</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br></div></div></li> <li><p><strong>第十步：</strong>  进入 C 语言的 <strong>main()</strong></p> <div class="language-c line-numbers-mode"><pre class="language-c"><code>bl     main                <span class="token comment">//带LR的子程序跳转, LR = pc - 4, 执行C层main函数</span>

LITE_OS_SEC_TEXT_INIT INT32 <span class="token function">main</span><span class="token punctuation">(</span>VOID<span class="token punctuation">)</span><span class="token comment">//由主CPU执行,默认0号CPU 为主CPU </span>
  <span class="token punctuation">{</span>
      UINT32 ret <span class="token operator">=</span> <span class="token function">OsMain</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">!=</span> LOS_OK<span class="token punctuation">)</span> <span class="token punctuation">{</span>
          <span class="token keyword">return</span> <span class="token punctuation">(</span>INT32<span class="token punctuation">)</span>LOS_NOK<span class="token punctuation">;</span>
      <span class="token punctuation">}</span>

      <span class="token function">CPU_MAP_SET</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token function">OsHwIDGet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//设置CPU映射,参数0 代表0号CPU</span>

      <span class="token function">OsSchedStart</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//调度开始</span>

      <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
          __asm <span class="token keyword">volatile</span><span class="token punctuation">(</span><span class="token string">&quot;wfi&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//WFI: wait for Interrupt 等待中断，即下一次中断发生前都在此hold住不干活</span>
      <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br></div></div></li></ul> <h3 id="百文说内核-抓住主脉络">百文说内核 | 抓住主脉络</h3> <ul><li>百文相当于摸出内核的肌肉和器官系统，让人开始丰满有立体感，因是直接从注释源码起步，在加注释过程中，每每有心得处就整理,慢慢形成了以下文章。内容立足源码，常以生活场景打比方尽可能多的将内核知识点置入某种场景，具有画面感，容易理解记忆。说别人能听得懂的话很重要! 百篇博客绝不是百度教条式的在说一堆诘屈聱牙的概念，那没什么意思。更希望让内核变得栩栩如生，倍感亲切。</li> <li>与代码需不断<code>debug</code>一样，文章内容会存在不少错漏之处，请多包涵，但会反复修正，持续更新，<code>v**.xx</code> 代表文章序号和修改的次数，精雕细琢，言简意赅，力求打造精品内容。</li> <li>百文在 &lt; 鸿蒙研究站 | 开源中国 | 博客园 | 51cto | csdn | 知乎 | 掘金 &gt; 站点发布，百篇博客系列目录如下。</li> <li><img src="https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/common/cate.png" alt=""></li></ul> <p>按功能模块:</p> <table><thead><tr><th style="text-align:center;">基础知识</th> <th style="text-align:center;">进程管理</th> <th style="text-align:center;">任务管理</th> <th style="text-align:center;">内存管理</th></tr></thead> <tbody><tr><td style="text-align:center;"><a href="http://weharmonyos.com/blog/01.html" target="_blank" rel="noopener noreferrer">双向链表</a><br><a href="http://weharmonyos.com/blog/02.html" target="_blank" rel="noopener noreferrer">内核概念</a><br><a href="http://weharmonyos.com/blog/03.html" target="_blank" rel="noopener noreferrer">源码结构</a><br><a href="http://weharmonyos.com/blog/04.html" target="_blank" rel="noopener noreferrer">地址空间</a><br><a href="http://weharmonyos.com/blog/05.html" target="_blank" rel="noopener noreferrer">计时单位</a><br><a href="http://weharmonyos.com/blog/06.html" target="_blank" rel="noopener noreferrer">优雅的宏</a><br><a href="http://weharmonyos.com/blog/07.html" target="_blank" rel="noopener noreferrer">钩子框架</a><br><a href="http://weharmonyos.com/blog/08.html" target="_blank" rel="noopener noreferrer">位图管理</a><br><a href="http://weharmonyos.com/blog/09.html" target="_blank" rel="noopener noreferrer">POSIX</a><br><a href="http://weharmonyos.com/blog/10.html" target="_blank" rel="noopener noreferrer">main函数</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/11.html" target="_blank" rel="noopener noreferrer">调度故事</a><br><a href="http://weharmonyos.com/blog/12.html" target="_blank" rel="noopener noreferrer">进程控制块</a><br><a href="http://weharmonyos.com/blog/13.html" target="_blank" rel="noopener noreferrer">进程空间</a><br><a href="http://weharmonyos.com/blog/14.html" target="_blank" rel="noopener noreferrer">线性区</a><br><a href="http://weharmonyos.com/blog/15.html" target="_blank" rel="noopener noreferrer">红黑树</a><br><a href="http://weharmonyos.com/blog/16.html" target="_blank" rel="noopener noreferrer">进程管理</a><br><a href="http://weharmonyos.com/blog/17.html" target="_blank" rel="noopener noreferrer">Fork进程</a><br><a href="http://weharmonyos.com/blog/18.html" target="_blank" rel="noopener noreferrer">进程回收</a><br><a href="http://weharmonyos.com/blog/19.html" target="_blank" rel="noopener noreferrer">Shell编辑</a><br><a href="http://weharmonyos.com/blog/20.html" target="_blank" rel="noopener noreferrer">Shell解析</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/21.html" target="_blank" rel="noopener noreferrer">任务控制块</a><br><a href="http://weharmonyos.com/blog/22.html" target="_blank" rel="noopener noreferrer">并发并行</a><br><a href="http://weharmonyos.com/blog/23.html" target="_blank" rel="noopener noreferrer">就绪队列</a><br><a href="http://weharmonyos.com/blog/24.html" target="_blank" rel="noopener noreferrer">调度机制</a><br><a href="http://weharmonyos.com/blog/25.html" target="_blank" rel="noopener noreferrer">任务管理</a><br><a href="http://weharmonyos.com/blog/26.html" target="_blank" rel="noopener noreferrer">用栈方式</a><br><a href="http://weharmonyos.com/blog/27.html" target="_blank" rel="noopener noreferrer">软件定时器</a><br><a href="http://weharmonyos.com/blog/28.html" target="_blank" rel="noopener noreferrer">控制台</a><br><a href="http://weharmonyos.com/blog/29.html" target="_blank" rel="noopener noreferrer">远程登录</a><br><a href="http://weharmonyos.com/blog/30.html" target="_blank" rel="noopener noreferrer">协议栈</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/31.html" target="_blank" rel="noopener noreferrer">内存规则</a><br><a href="http://weharmonyos.com/blog/32.html" target="_blank" rel="noopener noreferrer">物理内存</a><br><a href="http://weharmonyos.com/blog/33.html" target="_blank" rel="noopener noreferrer">内存概念</a><br><a href="http://weharmonyos.com/blog/34.html" target="_blank" rel="noopener noreferrer">虚实映射</a><br><a href="http://weharmonyos.com/blog/35.html" target="_blank" rel="noopener noreferrer">页表管理</a><br><a href="http://weharmonyos.com/blog/36.html" target="_blank" rel="noopener noreferrer">静态分配</a><br><a href="http://weharmonyos.com/blog/37.html" target="_blank" rel="noopener noreferrer">TLFS算法</a><br><a href="http://weharmonyos.com/blog/38.html" target="_blank" rel="noopener noreferrer">内存池管理</a><br><a href="http://weharmonyos.com/blog/39.html" target="_blank" rel="noopener noreferrer">原子操作</a><br><a href="http://weharmonyos.com/blog/40.html" target="_blank" rel="noopener noreferrer">圆整对齐</a><br></td></tr> <tr><td style="text-align:center;">通讯机制</td> <td style="text-align:center;">文件系统</td> <td style="text-align:center;">硬件架构</td> <td style="text-align:center;">内核汇编</td></tr> <tr><td style="text-align:center;"><a href="http://weharmonyos.com/blog/41.html" target="_blank" rel="noopener noreferrer">通讯总览</a><br><a href="http://weharmonyos.com/blog/42.html" target="_blank" rel="noopener noreferrer">自旋锁</a><br><a href="http://weharmonyos.com/blog/43.html" target="_blank" rel="noopener noreferrer">互斥锁</a><br><a href="http://weharmonyos.com/blog/44.html" target="_blank" rel="noopener noreferrer">快锁使用</a><br><a href="http://weharmonyos.com/blog/45.html" target="_blank" rel="noopener noreferrer">快锁实现</a><br><a href="http://weharmonyos.com/blog/46.html" target="_blank" rel="noopener noreferrer">读写锁</a><br><a href="http://weharmonyos.com/blog/47.html" target="_blank" rel="noopener noreferrer">信号量</a><br><a href="http://weharmonyos.com/blog/48.html" target="_blank" rel="noopener noreferrer">事件机制</a><br><a href="http://weharmonyos.com/blog/49.html" target="_blank" rel="noopener noreferrer">信号生产</a><br><a href="http://weharmonyos.com/blog/50.html" target="_blank" rel="noopener noreferrer">信号消费</a><br><a href="http://weharmonyos.com/blog/51.html" target="_blank" rel="noopener noreferrer">消息队列</a><br><a href="http://weharmonyos.com/blog/52.html" target="_blank" rel="noopener noreferrer">消息封装</a><br><a href="http://weharmonyos.com/blog/53.html" target="_blank" rel="noopener noreferrer">消息映射</a><br><a href="http://weharmonyos.com/blog/54.html" target="_blank" rel="noopener noreferrer">共享内存</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/55.html" target="_blank" rel="noopener noreferrer">文件概念</a><br><a href="http://weharmonyos.com/blog/56.html" target="_blank" rel="noopener noreferrer">文件故事</a><br><a href="http://weharmonyos.com/blog/57.html" target="_blank" rel="noopener noreferrer">索引节点</a><br><a href="http://weharmonyos.com/blog/58.html" target="_blank" rel="noopener noreferrer">VFS</a><br><a href="http://weharmonyos.com/blog/59.html" target="_blank" rel="noopener noreferrer">文件句柄</a><br><a href="http://weharmonyos.com/blog/60.html" target="_blank" rel="noopener noreferrer">根文件系统</a><br><a href="http://weharmonyos.com/blog/61.html" target="_blank" rel="noopener noreferrer">挂载机制</a><br><a href="http://weharmonyos.com/blog/62.html" target="_blank" rel="noopener noreferrer">管道文件</a><br><a href="http://weharmonyos.com/blog/63.html" target="_blank" rel="noopener noreferrer">文件映射</a><br><a href="http://weharmonyos.com/blog/64.html" target="_blank" rel="noopener noreferrer">写时拷贝</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/65.html" target="_blank" rel="noopener noreferrer">芯片模式</a><br><a href="http://weharmonyos.com/blog/66.html" target="_blank" rel="noopener noreferrer">ARM架构</a><br><a href="http://weharmonyos.com/blog/67.html" target="_blank" rel="noopener noreferrer">指令集</a><br><a href="http://weharmonyos.com/blog/68.html" target="_blank" rel="noopener noreferrer">协处理器</a><br><a href="http://weharmonyos.com/blog/69.html" target="_blank" rel="noopener noreferrer">工作模式</a><br><a href="http://weharmonyos.com/blog/70.html" target="_blank" rel="noopener noreferrer">寄存器</a><br><a href="http://weharmonyos.com/blog/71.html" target="_blank" rel="noopener noreferrer">多核管理</a><br><a href="http://weharmonyos.com/blog/72.html" target="_blank" rel="noopener noreferrer">中断概念</a><br><a href="http://weharmonyos.com/blog/73.html" target="_blank" rel="noopener noreferrer">中断管理</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/74.html" target="_blank" rel="noopener noreferrer">编码方式</a><br><a href="http://weharmonyos.com/blog/75.html" target="_blank" rel="noopener noreferrer">汇编基础</a><br><a href="http://weharmonyos.com/blog/76.html" target="_blank" rel="noopener noreferrer">汇编传参</a><br><a href="http://weharmonyos.com/blog/77.html" target="_blank" rel="noopener noreferrer">链接脚本</a><br><a href="http://weharmonyos.com/blog/78.html" target="_blank" rel="noopener noreferrer">内核启动</a><br><a href="http://weharmonyos.com/blog/79.html" target="_blank" rel="noopener noreferrer">进程切换</a><br><a href="http://weharmonyos.com/blog/80.html" target="_blank" rel="noopener noreferrer">任务切换</a><br><a href="http://weharmonyos.com/blog/81.html" target="_blank" rel="noopener noreferrer">中断切换</a><br><a href="http://weharmonyos.com/blog/82.html" target="_blank" rel="noopener noreferrer">异常接管</a><br><a href="http://weharmonyos.com/blog/83.html" target="_blank" rel="noopener noreferrer">缺页中断</a><br></td></tr> <tr><td style="text-align:center;">编译运行</td> <td style="text-align:center;">调测工具</td> <td style="text-align:center;"></td> <td style="text-align:center;"></td></tr> <tr><td style="text-align:center;"><a href="http://weharmonyos.com/blog/84.html" target="_blank" rel="noopener noreferrer">编译过程</a><br><a href="http://weharmonyos.com/blog/85.html" target="_blank" rel="noopener noreferrer">编译构建</a><br><a href="http://weharmonyos.com/blog/86.html" target="_blank" rel="noopener noreferrer">GN语法</a><br><a href="http://weharmonyos.com/blog/87.html" target="_blank" rel="noopener noreferrer">忍者无敌</a><br><a href="http://weharmonyos.com/blog/88.html" target="_blank" rel="noopener noreferrer">ELF格式</a><br><a href="http://weharmonyos.com/blog/89.html" target="_blank" rel="noopener noreferrer">ELF解析</a><br><a href="http://weharmonyos.com/blog/90.html" target="_blank" rel="noopener noreferrer">静态链接</a><br><a href="http://weharmonyos.com/blog/91.html" target="_blank" rel="noopener noreferrer">重定位</a><br><a href="http://weharmonyos.com/blog/92.html" target="_blank" rel="noopener noreferrer">动态链接</a><br><a href="http://weharmonyos.com/blog/93.html" target="_blank" rel="noopener noreferrer">进程映像</a><br><a href="http://weharmonyos.com/blog/94.html" target="_blank" rel="noopener noreferrer">应用启动</a><br><a href="http://weharmonyos.com/blog/95.html" target="_blank" rel="noopener noreferrer">系统调用</a><br><a href="http://weharmonyos.com/blog/96.html" target="_blank" rel="noopener noreferrer">VDSO</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/97.html" target="_blank" rel="noopener noreferrer">模块监控</a><br><a href="http://weharmonyos.com/blog/98.html" target="_blank" rel="noopener noreferrer">日志跟踪</a><br><a href="http://weharmonyos.com/blog/99.html" target="_blank" rel="noopener noreferrer">系统安全</a><br><a href="http://weharmonyos.com/blog/100.html" target="_blank" rel="noopener noreferrer">测试用例</a><br></td> <td style="text-align:center;"></td> <td style="text-align:center;"></td></tr></tbody></table> <h3 id="百万注源码-处处扣细节">百万注源码 | 处处扣细节</h3> <ul><li><p>百万汉字注解内核目的是要看清楚其毛细血管，细胞结构，等于在拿放大镜看内核。内核并不神秘，带着问题去源码中找答案是很容易上瘾的，你会发现很多文章对一些问题的解读是错误的，或者说不深刻难以自圆其说，你会慢慢形成自己新的解读，而新的解读又会碰到新的问题，如此层层递进，滚滚向前，拿着放大镜根本不愿意放手。</p></li> <li><p><a href="https://gitee.com/weharmony/kernel_liteos_a_note" target="_blank" rel="noopener noreferrer">&lt; gitee</a> | <a href="https://github.com/kuangyufei/kernel_liteos_a_note" target="_blank" rel="noopener noreferrer">github</a> | <a href="https://weharmony.coding.net/public/harmony/kernel_liteos_a_note/git/files" target="_blank" rel="noopener noreferrer">coding</a> | <a href="https://gitcode.net/kuangyufei/kernel_liteos_a_note" target="_blank" rel="noopener noreferrer">gitcode &gt;</a> 四大码仓推送 | 同步官方源码。</p> <p><a href="https://gitee.com/weharmony/kernel_liteos_a_note" target="_blank" rel="noopener noreferrer"><img src="https://gitee.com/weharmony/kernel_liteos_a_note/widgets/widget_card.svg?colors=393222,ebdfc1,fffae5,d8ca9f,393222,a28b40" alt=""></a></p></li></ul> <h3 id="关注不迷路-代码即人生">关注不迷路 | 代码即人生</h3> <p><img src="https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/common/so1so.png" alt=""></p> <ul><li>互联网从业十五年，计算机硕士，技术副总裁</li> <li>关注我，持续更新四十年，即聊技术也聊人生</li> <li>交有趣靠谱的人；做难而正确的事</li> <li>不做作，不炒作，只唯真</li> <li>不唯上，不唯书，只唯实</li></ul> <p><a href="http://weharmonyos.com/donate.html" target="_blank" rel="noopener noreferrer"> &gt;&gt; 捐助名单</a></p> <p>据说喜欢 <strong>点赞 + 分享</strong> 的,后来都成了大神。😃</p></div> <!----> <div class="content__content-bottom"></div> <footer class="page-meta"><!----> <!----> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev"><a href="/blog/77.html" class="prev"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon prev-icon"><path d="M906.783 588.79c-.02 8.499-6.882 15.36-15.38 15.37l-443.7-.01 75.704 191.682c2.52 6.42.482 13.763-5.038 17.91-5.52 4.168-13.138 4.147-18.616-.092L123.228 524.175a15.362 15.362 0 0 1-6-12.165c0-4.782 2.222-9.277 6-12.185L499.753 210.35a15.388 15.388 0 0 1 9.38-3.195c3.236 0 6.502 1.034 9.236 3.103 5.52 4.147 7.578 11.49 5.038 17.91L447.683 419.84l443.72-.01c8.498.01 15.36 6.881 15.36 15.36l.02 153.6z" fill="currentColor"></path></svg>
        链接脚本
      </a></span> <span class="next"><a href="/blog/79.html">
        进程切换
        <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon next-icon"><path d="M906.772 512c0 4.772-2.211 9.267-5.99 12.175L524.257 813.66a15.37 15.37 0 0 1-18.616.092 15.368 15.368 0 0 1-5.038-17.91l75.714-191.672h-443.73c-8.488 0-15.36-6.881-15.36-15.36v-153.6c0-8.489 6.872-15.36 15.36-15.36h443.73l-75.714-191.682a15.358 15.358 0 0 1 5.048-17.91c5.51-4.158 13.128-4.137 18.606.092l376.525 289.485a15.323 15.323 0 0 1 5.99 12.165z" fill="currentColor"></path></svg></a></span></p></div> <!----> <!----> <div class="content__page-bottom"></div></main> <!----></div><div class="global-ui"><!----><!----><div id="pwa-install"><!----> <div id="install-modal-wrapper" style="display:none;"><div class="background"></div> <div class="install-modal"><div class="header"><button aria-label="Close" class="close-button"><svg width="23" height="22" xmlns="http://www.w3.org/2000/svg" class="icon close-icon"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.12.358a1.224 1.224 0 011.729 0l8.92 8.914L20.686.358a1.224 1.224 0 011.73 1.728L13.497 11l8.92 8.913a1.222 1.222 0 11-1.73 1.729l-8.919-8.913-8.92 8.913a1.224 1.224 0 01-1.729-1.729L10.04 11l-8.92-8.914a1.222 1.222 0 010-1.728z" fill="currentColor"></path></svg></button> <div class="logo"><!----> <div class="title"><h1></h1> <p class="desc">This app can be installed on your PC or mobile device.  This will allow this web app to look and behave like any other installed app.  You will find it in your app lists and be able to pin it to your home screen, start menus or task bars.  This installed web app will also be able to safely interact with other apps and your operating system. </p></div></div></div> <div class="content"><div class="highlight"><!----> <!----></div> <div class="description"><h3>Description</h3> <p></p></div></div> <div class="button-wrapper"><button class="install-button">
        Install <span></span></button> <button class="cancel-button">
        Cancel
      </button></div></div></div></div><div tabindex="-1" role="dialog" aria-hidden="true" class="pswp"><div class="pswp__bg"></div> <div class="pswp__scroll-wrap"><div class="pswp__container"><div class="pswp__item"></div> <div class="pswp__item"></div> <div class="pswp__item"></div></div> <div class="pswp__ui pswp__ui--hidden"><div class="pswp__top-bar"><div class="pswp__counter"></div> <button title="Close" aria-label="Close" class="pswp__button pswp__button--close"></button> <button title="Share" aria-label="Share" class="pswp__button pswp__button--share"></button> <button title="Switch to full screen" aria-label="Switch to full screen" class="pswp__button pswp__button--fs"></button> <button title="Zoom in/out" aria-label="Zoom in/out" class="pswp__button pswp__button--zoom"></button> <div class="pswp__preloader"><div class="pswp__preloader__icn"><div class="pswp__preloader__cut"><div class="pswp__preloader__donut"></div></div></div></div></div> <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap"><div class="pswp__share-tooltip"></div></div> <button title="Prev (Arrow Left)" aria-label="Prev (Arrow Left)" class="pswp__button pswp__button--arrow--left"></button> <button title="Next (Arrow Right)" aria-label="Next (Arrow Right)" class="pswp__button pswp__button--arrow--right"></button> <div class="pswp__caption"><div class="pswp__caption__center"></div></div></div></div></div></div></div>
    <script src="/assets/js/app.9a8b95d8.js" defer></script><script src="/assets/js/vendors~layout-Layout.c1e797d4.js" defer></script><script src="/assets/js/vendors~layout-Blog~layout-Layout~layout-NotFound.f75cf258.js" defer></script><script src="/assets/js/page--63d3c5b0.b587d38f.js" defer></script>
  </body>
</html>
